From 7ec0faca1e28c9dd7a4d7a9513cbb5067a9b77c1 Mon Sep 17 00:00:00 2001 From: "Markus F.X.J. Oberhumer" Date: Sun, 9 Jul 2023 17:36:24 +0200 Subject: [PATCH] all: misc and noexcept updates --- .../workflows/static-analyzer-clang-tidy.yml | 4 +- CMakeLists.txt | 2 +- Makefile | 3 +- .../10-create-image.sh | 1 + .../20-image-run-shell.sh | 2 +- .../10-create-image.sh | 1 + .../20-image-run-shell.sh | 2 +- misc/scripts/run-clang-tidy.py | 504 ++++++++++++++++++ misc/test-qemu-with-podman/README.md | 9 +- .../10-create-image.sh | 5 +- .../20-image-run-shell.sh | 2 +- .../Dockerfile | 0 .../10-create-image.sh | 5 +- .../20-image-run-shell.sh | 2 +- .../Dockerfile | 0 .../10-create-image.sh | 5 +- .../20-image-run-shell.sh | 2 +- .../Dockerfile | 0 src/bele_policy.h | 12 +- src/compress/compress_lzma.cpp | 1 - src/conf.h | 2 +- src/file.cpp | 2 +- src/file.h | 4 +- src/headers.h | 1 + src/lefile.cpp | 2 +- src/lefile.h | 6 +- src/main.cpp | 4 +- src/p_w32pe_i386.cpp | 2 +- src/p_w32pe_i386.h | 2 +- src/p_w64pe_amd64.cpp | 2 +- src/p_w64pe_amd64.h | 2 +- src/p_w64pe_arm64.h | 2 +- src/p_wince_arm.cpp | 2 +- src/p_wince_arm.h | 2 +- src/packer.h | 4 +- src/pefile.cpp | 16 +- src/pefile.h | 14 +- src/util/membuffer.h | 6 +- src/util/util.cpp | 3 +- src/util/xspan_impl_common.h | 8 +- src/util/xspan_impl_ptr.h | 10 +- 41 files changed, 589 insertions(+), 69 deletions(-) create mode 100755 misc/scripts/run-clang-tidy.py rename misc/test-qemu-with-podman/{test-qemu6-with-podman => test-qemu6-alpine}/10-create-image.sh (63%) rename misc/test-qemu-with-podman/{test-qemu8-with-podman => test-qemu6-alpine}/20-image-run-shell.sh (96%) rename misc/test-qemu-with-podman/{test-qemu6-with-podman => test-qemu6-alpine}/Dockerfile (100%) rename misc/test-qemu-with-podman/{test-qemu8-with-podman => test-qemu7-alpine}/10-create-image.sh (63%) rename misc/test-qemu-with-podman/{test-qemu6-with-podman => test-qemu7-alpine}/20-image-run-shell.sh (96%) rename misc/test-qemu-with-podman/{test-qemu7-with-podman => test-qemu7-alpine}/Dockerfile (100%) rename misc/test-qemu-with-podman/{test-qemu7-with-podman => test-qemu8-alpine}/10-create-image.sh (63%) rename misc/test-qemu-with-podman/{test-qemu7-with-podman => test-qemu8-alpine}/20-image-run-shell.sh (96%) rename misc/test-qemu-with-podman/{test-qemu8-with-podman => test-qemu8-alpine}/Dockerfile (100%) diff --git a/.github/workflows/static-analyzer-clang-tidy.yml b/.github/workflows/static-analyzer-clang-tidy.yml index d74db32d..4ae52186 100644 --- a/.github/workflows/static-analyzer-clang-tidy.yml +++ b/.github/workflows/static-analyzer-clang-tidy.yml @@ -23,9 +23,9 @@ jobs: - name: 'Perform clang-tidy Analysis Debug' run: | make -C upx build/extra/clang/debug - run-clang-tidy -p upx/build/extra/clang/debug + python3 upx/misc/scripts/run-clang-tidy.py -p upx/build/extra/clang/debug - name: 'Perform clang-tidy Analysis Release' if: success() || failure() # run this step even if the previous step failed run: | make -C upx build/extra/clang/release - run-clang-tidy -p upx/build/extra/clang/release + python3 upx/misc/scripts/run-clang-tidy.py -p upx/build/extra/clang/release diff --git a/CMakeLists.txt b/CMakeLists.txt index ba840458..44b5b942 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -173,7 +173,7 @@ else() add_definitions(-fno-strict-aliasing -fno-strict-overflow -funsigned-char) # disable overambitious auto-vectorization until this actually gains something add_definitions(-fno-tree-vectorize) - # disable annoying clang warnings which get added by the Apple Xcode cmake generator + # disable annoying clang warnings which get added by the macOS Xcode cmake generator if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND CMAKE_GENERATOR STREQUAL "Xcode") add_definitions(-Wno-shorten-64-to-32) endif() diff --git a/Makefile b/Makefile index 7582c86d..f302cf2b 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,6 @@ # # INFO: this Makefile is just a convenience wrapper for calling CMake -# (using a somewhat current CMake version is highly recommended) # HINT: if you only have an older CMake 3.x then you can invoke cmake manually like this: # mkdir -p build/release @@ -143,7 +142,7 @@ build/extra/cross-windows-mingw64/release: PHONY; $(call run_config_and_build,$@ build/extra/cross-windows-mingw64/%: export CC = x86_64-w64-mingw32-gcc -static build/extra/cross-windows-mingw64/%: export CXX = x86_64-w64-mingw32-g++ -static -# cross compiler: macOS arm64 +# cross compiler: macOS arm64 (aarch64) build/extra/cross-darwin-arm64/debug: PHONY; $(call run_config_and_build,$@,Debug) build/extra/cross-darwin-arm64/release: PHONY; $(call run_config_and_build,$@,Release) build/extra/cross-darwin-arm64/%: export CC = clang -target arm64-apple-darwin diff --git a/misc/cross-compile-upx-with-podman/10-create-image.sh b/misc/cross-compile-upx-with-podman/10-create-image.sh index a755bd6b..69689475 100755 --- a/misc/cross-compile-upx-with-podman/10-create-image.sh +++ b/misc/cross-compile-upx-with-podman/10-create-image.sh @@ -10,6 +10,7 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" # so you have to create that image first # WARNING: we install many packages, so the resulting image needs A LOT of disk space! image=upx-cross-compile-20230115-v4 +[[ $1 == --print-image ]] && echo "$image" && exit 0 podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir" diff --git a/misc/cross-compile-upx-with-podman/20-image-run-shell.sh b/misc/cross-compile-upx-with-podman/20-image-run-shell.sh index 9d4d0ad4..204881c3 100755 --- a/misc/cross-compile-upx-with-podman/20-image-run-shell.sh +++ b/misc/cross-compile-upx-with-podman/20-image-run-shell.sh @@ -6,7 +6,7 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" # run an interactive shell in the image # using a rootless Podman container -image=upx-cross-compile-20230115-v4 +image="$("$argv0dir/10-create-image.sh" --print-image)" flags=( --read-only --rm --pull=never ) flags+=( --cap-drop=all ) # drop all capabilities diff --git a/misc/rebuild-stubs-with-podman/10-create-image.sh b/misc/rebuild-stubs-with-podman/10-create-image.sh index fd0ab06e..fb628077 100755 --- a/misc/rebuild-stubs-with-podman/10-create-image.sh +++ b/misc/rebuild-stubs-with-podman/10-create-image.sh @@ -7,6 +7,7 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" # using a rootless Podman container image=upx-stubtools-20221212-v6 +[[ $1 == --print-image ]] && echo "$image" && exit 0 podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir" diff --git a/misc/rebuild-stubs-with-podman/20-image-run-shell.sh b/misc/rebuild-stubs-with-podman/20-image-run-shell.sh index 0e49a74b..1b3a2895 100755 --- a/misc/rebuild-stubs-with-podman/20-image-run-shell.sh +++ b/misc/rebuild-stubs-with-podman/20-image-run-shell.sh @@ -6,7 +6,7 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" # run an interactive shell in the image # using a rootless Podman container -image=upx-stubtools-20221212-v6 +image="$("$argv0dir/10-create-image.sh" --print-image)" flags=( --read-only --rm --pull=never ) flags+=( --cap-drop=all ) # drop all capabilities diff --git a/misc/scripts/run-clang-tidy.py b/misc/scripts/run-clang-tidy.py new file mode 100755 index 00000000..7cc4022a --- /dev/null +++ b/misc/scripts/run-clang-tidy.py @@ -0,0 +1,504 @@ +#!/usr/bin/env python3 +# +# ===- run-clang-tidy.py - Parallel clang-tidy runner --------*- python -*--===# +# +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +# ===-----------------------------------------------------------------------===# +# FIXME: Integrate with clang-tidy-diff.py + + +""" +Parallel clang-tidy runner +========================== + +Runs clang-tidy over all files in a compilation database. Requires clang-tidy +and clang-apply-replacements in $PATH. + +Example invocations. +- Run clang-tidy on all files in the current working directory with a default + set of checks and show warnings in the cpp files and all project headers. + run-clang-tidy.py $PWD + +- Fix all header guards. + run-clang-tidy.py -fix -checks=-*,llvm-header-guard + +- Fix all header guards included from clang-tidy and header guards + for clang-tidy headers. + run-clang-tidy.py -fix -checks=-*,llvm-header-guard extra/clang-tidy \ + -header-filter=extra/clang-tidy + +Compilation database setup: +http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html +""" + +from __future__ import print_function + +import argparse +import glob +import json +import multiprocessing +import os +import queue +import re +import shutil +import subprocess +import sys +import tempfile +import threading +import traceback + +try: + import yaml +except ImportError: + yaml = None + + +def strtobool(val): + """Convert a string representation of truth to a bool following LLVM's CLI argument parsing.""" + + val = val.lower() + if val in ["", "true", "1"]: + return True + elif val in ["false", "0"]: + return False + + # Return ArgumentTypeError so that argparse does not substitute its own error message + raise argparse.ArgumentTypeError( + "'{}' is invalid value for boolean argument! Try 0 or 1.".format(val) + ) + + +def find_compilation_database(path): + """Adjusts the directory until a compilation database is found.""" + result = os.path.realpath("./") + while not os.path.isfile(os.path.join(result, path)): + parent = os.path.dirname(result) + if result == parent: + print("Error: could not find compilation database.") + sys.exit(1) + result = parent + return result + + +def make_absolute(f, directory): + if os.path.isabs(f): + return f + return os.path.normpath(os.path.join(directory, f)) + + +def get_tidy_invocation( + f, + clang_tidy_binary, + checks, + tmpdir, + build_path, + header_filter, + allow_enabling_alpha_checkers, + extra_arg, + extra_arg_before, + quiet, + config_file_path, + config, + line_filter, + use_color, + plugins, + warnings_as_errors, +): + """Gets a command line for clang-tidy.""" + start = [clang_tidy_binary] + if allow_enabling_alpha_checkers: + start.append("-allow-enabling-analyzer-alpha-checkers") + if header_filter is not None: + start.append("-header-filter=" + header_filter) + if line_filter is not None: + start.append("-line-filter=" + line_filter) + if use_color is not None: + if use_color: + start.append("--use-color") + else: + start.append("--use-color=false") + if checks: + start.append("-checks=" + checks) + if tmpdir is not None: + start.append("-export-fixes") + # Get a temporary file. We immediately close the handle so clang-tidy can + # overwrite it. + (handle, name) = tempfile.mkstemp(suffix=".yaml", dir=tmpdir) + os.close(handle) + start.append(name) + for arg in extra_arg: + start.append("-extra-arg=%s" % arg) + for arg in extra_arg_before: + start.append("-extra-arg-before=%s" % arg) + start.append("-p=" + build_path) + if quiet: + start.append("-quiet") + if config_file_path: + start.append("--config-file=" + config_file_path) + elif config: + start.append("-config=" + config) + for plugin in plugins: + start.append("-load=" + plugin) + if warnings_as_errors: + start.append("--warnings-as-errors=" + warnings_as_errors) + start.append(f) + return start + + +def merge_replacement_files(tmpdir, mergefile): + """Merge all replacement files in a directory into a single file""" + # The fixes suggested by clang-tidy >= 4.0.0 are given under + # the top level key 'Diagnostics' in the output yaml files + mergekey = "Diagnostics" + merged = [] + for replacefile in glob.iglob(os.path.join(tmpdir, "*.yaml")): + content = yaml.safe_load(open(replacefile, "r")) + if not content: + continue # Skip empty files. + merged.extend(content.get(mergekey, [])) + + if merged: + # MainSourceFile: The key is required by the definition inside + # include/clang/Tooling/ReplacementsYaml.h, but the value + # is actually never used inside clang-apply-replacements, + # so we set it to '' here. + output = {"MainSourceFile": "", mergekey: merged} + with open(mergefile, "w") as out: + yaml.safe_dump(output, out) + else: + # Empty the file: + open(mergefile, "w").close() + + +def find_binary(arg, name, build_path): + """Get the path for a binary or exit""" + if arg: + if shutil.which(arg): + return arg + else: + raise SystemExit( + "error: passed binary '{}' was not found or is not executable".format( + arg + ) + ) + + built_path = os.path.join(build_path, "bin", name) + binary = shutil.which(name) or shutil.which(built_path) + if binary: + return binary + else: + raise SystemExit( + "error: failed to find {} in $PATH or at {}".format(name, built_path) + ) + + +def apply_fixes(args, clang_apply_replacements_binary, tmpdir): + """Calls clang-apply-fixes on a given directory.""" + invocation = [clang_apply_replacements_binary] + invocation.append("-ignore-insert-conflict") + if args.format: + invocation.append("-format") + if args.style: + invocation.append("-style=" + args.style) + invocation.append(tmpdir) + subprocess.call(invocation) + + +def run_tidy(args, clang_tidy_binary, tmpdir, build_path, queue, lock, failed_files): + """Takes filenames out of queue and runs clang-tidy on them.""" + while True: + name = queue.get() + invocation = get_tidy_invocation( + name, + clang_tidy_binary, + args.checks, + tmpdir, + build_path, + args.header_filter, + args.allow_enabling_alpha_checkers, + args.extra_arg, + args.extra_arg_before, + args.quiet, + args.config_file, + args.config, + args.line_filter, + args.use_color, + args.plugins, + args.warnings_as_errors, + ) + + proc = subprocess.Popen( + invocation, stdout=subprocess.PIPE, stderr=subprocess.PIPE + ) + output, err = proc.communicate() + if proc.returncode != 0: + if proc.returncode < 0: + msg = "%s: terminated by signal %d\n" % (name, -proc.returncode) + err += msg.encode("utf-8") + failed_files.append(name) + with lock: + sys.stdout.write(" ".join(invocation) + "\n" + output.decode("utf-8")) + if len(err) > 0: + sys.stdout.flush() + sys.stderr.write(err.decode("utf-8")) + queue.task_done() + + +def main(): + parser = argparse.ArgumentParser( + description="Runs clang-tidy over all files " + "in a compilation database. Requires " + "clang-tidy and clang-apply-replacements in " + "$PATH or in your build directory." + ) + parser.add_argument( + "-allow-enabling-alpha-checkers", + action="store_true", + help="allow alpha checkers from " "clang-analyzer.", + ) + parser.add_argument( + "-clang-tidy-binary", metavar="PATH", help="path to clang-tidy binary" + ) + parser.add_argument( + "-clang-apply-replacements-binary", + metavar="PATH", + help="path to clang-apply-replacements binary", + ) + parser.add_argument( + "-checks", + default=None, + help="checks filter, when not specified, use clang-tidy " "default", + ) + config_group = parser.add_mutually_exclusive_group() + config_group.add_argument( + "-config", + default=None, + help="Specifies a configuration in YAML/JSON format: " + " -config=\"{Checks: '*', " + ' CheckOptions: {x: y}}" ' + "When the value is empty, clang-tidy will " + "attempt to find a file named .clang-tidy for " + "each source file in its parent directories.", + ) + config_group.add_argument( + "-config-file", + default=None, + help="Specify the path of .clang-tidy or custom config " + "file: e.g. -config-file=/some/path/myTidyConfigFile. " + "This option internally works exactly the same way as " + "-config option after reading specified config file. " + "Use either -config-file or -config, not both.", + ) + parser.add_argument( + "-header-filter", + default=None, + help="regular expression matching the names of the " + "headers to output diagnostics from. Diagnostics from " + "the main file of each translation unit are always " + "displayed.", + ) + parser.add_argument( + "-line-filter", + default=None, + help="List of files with line ranges to filter the" "warnings.", + ) + if yaml: + parser.add_argument( + "-export-fixes", + metavar="filename", + dest="export_fixes", + help="Create a yaml file to store suggested fixes in, " + "which can be applied with clang-apply-replacements.", + ) + parser.add_argument( + "-j", + type=int, + default=0, + help="number of tidy instances to be run in parallel.", + ) + parser.add_argument( + "files", nargs="*", default=[".*"], help="files to be processed (regex on path)" + ) + parser.add_argument("-fix", action="store_true", help="apply fix-its") + parser.add_argument( + "-format", action="store_true", help="Reformat code " "after applying fixes" + ) + parser.add_argument( + "-style", + default="file", + help="The style of reformat " "code after applying fixes", + ) + parser.add_argument( + "-use-color", + type=strtobool, + nargs="?", + const=True, + help="Use colors in diagnostics, overriding clang-tidy's" + " default behavior. This option overrides the 'UseColor" + "' option in .clang-tidy file, if any.", + ) + parser.add_argument( + "-p", dest="build_path", help="Path used to read a compile command database." + ) + parser.add_argument( + "-extra-arg", + dest="extra_arg", + action="append", + default=[], + help="Additional argument to append to the compiler " "command line.", + ) + parser.add_argument( + "-extra-arg-before", + dest="extra_arg_before", + action="append", + default=[], + help="Additional argument to prepend to the compiler " "command line.", + ) + parser.add_argument( + "-quiet", action="store_true", help="Run clang-tidy in quiet mode" + ) + parser.add_argument( + "-load", + dest="plugins", + action="append", + default=[], + help="Load the specified plugin in clang-tidy.", + ) + parser.add_argument( + "-warnings-as-errors", + default=None, + help="Upgrades warnings to errors. Same format as " "'-checks'", + ) + args = parser.parse_args() + + db_path = "compile_commands.json" + + if args.build_path is not None: + build_path = args.build_path + else: + # Find our database + build_path = find_compilation_database(db_path) + + clang_tidy_binary = find_binary(args.clang_tidy_binary, "clang-tidy", build_path) + + tmpdir = None + if args.fix: + clang_apply_replacements_binary = find_binary( + args.clang_apply_replacements_binary, "clang-apply-replacements", build_path + ) + tmpdir = tempfile.mkdtemp() + + try: + invocation = get_tidy_invocation( + "", + clang_tidy_binary, + args.checks, + None, + build_path, + args.header_filter, + args.allow_enabling_alpha_checkers, + args.extra_arg, + args.extra_arg_before, + args.quiet, + args.config_file, + args.config, + args.line_filter, + args.use_color, + args.plugins, + args.warnings_as_errors, + ) + invocation.append("-list-checks") + invocation.append("-") + if args.quiet: + # Even with -quiet we still want to check if we can call clang-tidy. + with open(os.devnull, "w") as dev_null: + subprocess.check_call(invocation, stdout=dev_null) + else: + subprocess.check_call(invocation) + except: + print("Unable to run clang-tidy.", file=sys.stderr) + sys.exit(1) + + # Load the database and extract all files. + database = json.load(open(os.path.join(build_path, db_path))) + files = set( + [make_absolute(entry["file"], entry["directory"]) for entry in database] + ) + files = sorted(list(files)) + + max_task = args.j + if max_task == 0: + max_task = multiprocessing.cpu_count() + + # Build up a big regexy filter from all command line arguments. + file_name_re = re.compile("|".join(args.files)) + + return_code = 0 + try: + # Spin up a bunch of tidy-launching threads. + task_queue = queue.Queue(max_task) + # List of files with a non-zero return code. + failed_files = [] + lock = threading.Lock() + for _ in range(max_task): + t = threading.Thread( + target=run_tidy, + args=( + args, + clang_tidy_binary, + tmpdir, + build_path, + task_queue, + lock, + failed_files, + ), + ) + t.daemon = True + t.start() + + # Fill the queue with files. + for name in files: + if file_name_re.search(name): + task_queue.put(name) + + # Wait for all threads to be done. + task_queue.join() + if len(failed_files): + return_code = 1 + + except KeyboardInterrupt: + # This is a sad hack. Unfortunately subprocess goes + # bonkers with ctrl-c and we start forking merrily. + print("\nCtrl-C detected, goodbye.") + if tmpdir: + shutil.rmtree(tmpdir) + os.kill(0, 9) + + if yaml and args.export_fixes: + print("Writing fixes to " + args.export_fixes + " ...") + try: + merge_replacement_files(tmpdir, args.export_fixes) + except: + print("Error exporting fixes.\n", file=sys.stderr) + traceback.print_exc() + return_code = 1 + + if args.fix: + print("Applying fixes ...") + try: + apply_fixes(args, clang_apply_replacements_binary, tmpdir) + except: + print("Error applying fixes.\n", file=sys.stderr) + traceback.print_exc() + return_code = 1 + + if tmpdir: + shutil.rmtree(tmpdir) + sys.exit(return_code) + + +if __name__ == "__main__": + main() diff --git a/misc/test-qemu-with-podman/README.md b/misc/test-qemu-with-podman/README.md index 9bb6b40e..65cf74b1 100644 --- a/misc/test-qemu-with-podman/README.md +++ b/misc/test-qemu-with-podman/README.md @@ -1,7 +1,7 @@ test-qemu-with-podman ===================== -This directory provides scripts for creating and running small Alpine Linux container +This directory provides scripts for creating and running rather small Alpine Linux container images, intended for testing statically-linked Linux executables with qemu-user. Very short usage instructions follow. @@ -19,13 +19,16 @@ Very short usage instructions follow. mkdir -p tmp cd tmp - # download some official UPX release binaries + # download official UPX release binaries wget https://github.com/upx/upx/releases/download/v4.0.2/upx-4.0.2-amd64_linux.tar.xz wget https://github.com/upx/upx/releases/download/v4.0.2/upx-4.0.2-arm64_linux.tar.xz + wget https://github.com/upx/upx/releases/download/v4.0.2/upx-4.0.2-armeb_linux.tar.xz + wget https://github.com/upx/upx/releases/download/v4.0.2/upx-4.0.2-arm_linux.tar.xz wget https://github.com/upx/upx/releases/download/v4.0.2/upx-4.0.2-i386_linux.tar.xz + wget https://github.com/upx/upx/releases/download/v4.0.2/upx-4.0.2-mipsel_linux.tar.xz wget https://github.com/upx/upx/releases/download/v4.0.2/upx-4.0.2-mips_linux.tar.xz wget https://github.com/upx/upx/releases/download/v4.0.2/upx-4.0.2-powerpc64le_linux.tar.xz - # ...same for more architectures + wget https://github.com/upx/upx/releases/download/v4.0.2/upx-4.0.2-powerpc_linux.tar.xz # and unpack all .tar.xz files for f in ./upx*.tar.xz; do tar -xJf $f; done diff --git a/misc/test-qemu-with-podman/test-qemu6-with-podman/10-create-image.sh b/misc/test-qemu-with-podman/test-qemu6-alpine/10-create-image.sh similarity index 63% rename from misc/test-qemu-with-podman/test-qemu6-with-podman/10-create-image.sh rename to misc/test-qemu-with-podman/test-qemu6-alpine/10-create-image.sh index 08614c61..4679188c 100755 --- a/misc/test-qemu-with-podman/test-qemu6-with-podman/10-create-image.sh +++ b/misc/test-qemu-with-podman/test-qemu6-alpine/10-create-image.sh @@ -6,9 +6,10 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" # create the image from Dockerfile # using a rootless Podman container -image=upx-test-qemu6-20230708-v1 +image=upx-test-qemu6-alpine-20230708-v1 +[[ $1 == --print-image ]] && echo "$image" && exit 0 -podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir" +podman build --squash -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir" podman image list "$image" echo diff --git a/misc/test-qemu-with-podman/test-qemu8-with-podman/20-image-run-shell.sh b/misc/test-qemu-with-podman/test-qemu6-alpine/20-image-run-shell.sh similarity index 96% rename from misc/test-qemu-with-podman/test-qemu8-with-podman/20-image-run-shell.sh rename to misc/test-qemu-with-podman/test-qemu6-alpine/20-image-run-shell.sh index 03799b2c..1f83802d 100755 --- a/misc/test-qemu-with-podman/test-qemu8-with-podman/20-image-run-shell.sh +++ b/misc/test-qemu-with-podman/test-qemu6-alpine/20-image-run-shell.sh @@ -6,7 +6,7 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" # run an interactive shell in the image # using a rootless Podman container -image=upx-test-qemu8-20230708-v1 +image="$("$argv0dir/10-create-image.sh" --print-image)" flags=( --read-only --rm --pull=never ) flags+=( --cap-drop=all ) # drop all capabilities diff --git a/misc/test-qemu-with-podman/test-qemu6-with-podman/Dockerfile b/misc/test-qemu-with-podman/test-qemu6-alpine/Dockerfile similarity index 100% rename from misc/test-qemu-with-podman/test-qemu6-with-podman/Dockerfile rename to misc/test-qemu-with-podman/test-qemu6-alpine/Dockerfile diff --git a/misc/test-qemu-with-podman/test-qemu8-with-podman/10-create-image.sh b/misc/test-qemu-with-podman/test-qemu7-alpine/10-create-image.sh similarity index 63% rename from misc/test-qemu-with-podman/test-qemu8-with-podman/10-create-image.sh rename to misc/test-qemu-with-podman/test-qemu7-alpine/10-create-image.sh index 947477aa..e6316a04 100755 --- a/misc/test-qemu-with-podman/test-qemu8-with-podman/10-create-image.sh +++ b/misc/test-qemu-with-podman/test-qemu7-alpine/10-create-image.sh @@ -6,9 +6,10 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" # create the image from Dockerfile # using a rootless Podman container -image=upx-test-qemu8-20230708-v1 +image=upx-test-qemu7-alpine-20230708-v1 +[[ $1 == --print-image ]] && echo "$image" && exit 0 -podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir" +podman build --squash -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir" podman image list "$image" echo diff --git a/misc/test-qemu-with-podman/test-qemu6-with-podman/20-image-run-shell.sh b/misc/test-qemu-with-podman/test-qemu7-alpine/20-image-run-shell.sh similarity index 96% rename from misc/test-qemu-with-podman/test-qemu6-with-podman/20-image-run-shell.sh rename to misc/test-qemu-with-podman/test-qemu7-alpine/20-image-run-shell.sh index ebbb838f..1f83802d 100755 --- a/misc/test-qemu-with-podman/test-qemu6-with-podman/20-image-run-shell.sh +++ b/misc/test-qemu-with-podman/test-qemu7-alpine/20-image-run-shell.sh @@ -6,7 +6,7 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" # run an interactive shell in the image # using a rootless Podman container -image=upx-test-qemu6-20230708-v1 +image="$("$argv0dir/10-create-image.sh" --print-image)" flags=( --read-only --rm --pull=never ) flags+=( --cap-drop=all ) # drop all capabilities diff --git a/misc/test-qemu-with-podman/test-qemu7-with-podman/Dockerfile b/misc/test-qemu-with-podman/test-qemu7-alpine/Dockerfile similarity index 100% rename from misc/test-qemu-with-podman/test-qemu7-with-podman/Dockerfile rename to misc/test-qemu-with-podman/test-qemu7-alpine/Dockerfile diff --git a/misc/test-qemu-with-podman/test-qemu7-with-podman/10-create-image.sh b/misc/test-qemu-with-podman/test-qemu8-alpine/10-create-image.sh similarity index 63% rename from misc/test-qemu-with-podman/test-qemu7-with-podman/10-create-image.sh rename to misc/test-qemu-with-podman/test-qemu8-alpine/10-create-image.sh index 294b5ec7..8b0a0232 100755 --- a/misc/test-qemu-with-podman/test-qemu7-with-podman/10-create-image.sh +++ b/misc/test-qemu-with-podman/test-qemu8-alpine/10-create-image.sh @@ -6,9 +6,10 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" # create the image from Dockerfile # using a rootless Podman container -image=upx-test-qemu7-20230708-v1 +image=upx-test-qemu8-alpine-20230708-v1 +[[ $1 == --print-image ]] && echo "$image" && exit 0 -podman build -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir" +podman build --squash -t "$image" -f "$argv0dir/Dockerfile" "$argv0dir" podman image list "$image" echo diff --git a/misc/test-qemu-with-podman/test-qemu7-with-podman/20-image-run-shell.sh b/misc/test-qemu-with-podman/test-qemu8-alpine/20-image-run-shell.sh similarity index 96% rename from misc/test-qemu-with-podman/test-qemu7-with-podman/20-image-run-shell.sh rename to misc/test-qemu-with-podman/test-qemu8-alpine/20-image-run-shell.sh index c1c5e6dd..1f83802d 100755 --- a/misc/test-qemu-with-podman/test-qemu7-with-podman/20-image-run-shell.sh +++ b/misc/test-qemu-with-podman/test-qemu8-alpine/20-image-run-shell.sh @@ -6,7 +6,7 @@ argv0=$0; argv0abs="$(readlink -fn "$argv0")"; argv0dir="$(dirname "$argv0abs")" # run an interactive shell in the image # using a rootless Podman container -image=upx-test-qemu7-20230708-v1 +image="$("$argv0dir/10-create-image.sh" --print-image)" flags=( --read-only --rm --pull=never ) flags+=( --cap-drop=all ) # drop all capabilities diff --git a/misc/test-qemu-with-podman/test-qemu8-with-podman/Dockerfile b/misc/test-qemu-with-podman/test-qemu8-alpine/Dockerfile similarity index 100% rename from misc/test-qemu-with-podman/test-qemu8-with-podman/Dockerfile rename to misc/test-qemu-with-podman/test-qemu8-alpine/Dockerfile diff --git a/src/bele_policy.h b/src/bele_policy.h index 38f5cc52..dd645ae1 100644 --- a/src/bele_policy.h +++ b/src/bele_policy.h @@ -81,8 +81,8 @@ private: // disable copy and move AbstractPolicy(const AbstractPolicy &) = delete; AbstractPolicy &operator=(const AbstractPolicy &) = delete; - AbstractPolicy(AbstractPolicy &&) = delete; - AbstractPolicy &operator=(AbstractPolicy &&) = delete; + AbstractPolicy(AbstractPolicy &&) noexcept = delete; + AbstractPolicy &operator=(AbstractPolicy &&) noexcept = delete; // disable dynamic allocation ACC_CXX_DISABLE_NEW_DELETE }; @@ -149,8 +149,8 @@ private: // disable copy and move BEPolicy(const BEPolicy &) = delete; BEPolicy &operator=(const BEPolicy &) = delete; - BEPolicy(BEPolicy &&) = delete; - BEPolicy &operator=(BEPolicy &&) = delete; + BEPolicy(BEPolicy &&) noexcept = delete; + BEPolicy &operator=(BEPolicy &&) noexcept = delete; // disable dynamic allocation ACC_CXX_DISABLE_NEW_DELETE }; @@ -211,8 +211,8 @@ private: // disable copy and move LEPolicy(const LEPolicy &) = delete; LEPolicy &operator=(const LEPolicy &) = delete; - LEPolicy(LEPolicy &&) = delete; - LEPolicy &operator=(LEPolicy &&) = delete; + LEPolicy(LEPolicy &&) noexcept = delete; + LEPolicy &operator=(LEPolicy &&) noexcept = delete; // disable dynamic allocation ACC_CXX_DISABLE_NEW_DELETE }; diff --git a/src/compress/compress_lzma.cpp b/src/compress/compress_lzma.cpp index c6d4c198..1f74c1e9 100644 --- a/src/compress/compress_lzma.cpp +++ b/src/compress/compress_lzma.cpp @@ -208,7 +208,6 @@ error: // ensure proper nullptr usage // TODO later: examine why we need this in the first place -#include #undef NULL // NOLINTBEGIN(clang-analyzer-optin.cplusplus.*) #define NULL nullptr diff --git a/src/conf.h b/src/conf.h index b3a1a3d2..fb52e1e6 100644 --- a/src/conf.h +++ b/src/conf.h @@ -412,7 +412,7 @@ noinline void throwAssertFailed(const char *expr, const char *file, int line, co #if defined(__GNUC__) #undef assert #if DEBUG || 0 -// generate a warning if assert() is used inside a "noexcept" function +// generate a warning if assert() is used inside a "noexcept" context #define assert(e) ((void)(__acc_cte(e) || (assertFailed(#e, __FILE__, __LINE__, __func__), throw 1, 0))) #else // turn assertion failures into exceptions diff --git a/src/file.cpp b/src/file.cpp index 3a94929a..c6775c8a 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -93,7 +93,7 @@ bool FileBase::do_sopen() { return true; } -bool FileBase::close() { +bool FileBase::close() noexcept { bool ok = true; if (isOpen() && _fd != STDIN_FILENO && _fd != STDOUT_FILENO && _fd != STDERR_FILENO) if (::close(_fd) == -1) diff --git a/src/file.h b/src/file.h index 3f49f1de..86b3d73c 100644 --- a/src/file.h +++ b/src/file.h @@ -37,7 +37,7 @@ protected: virtual ~FileBase(); public: - bool close(); + bool close() noexcept; void closex(); bool isOpen() const { return _fd >= 0; } int getFd() const { return _fd; } @@ -77,7 +77,6 @@ class InputFile final : public FileBase { public: InputFile() = default; - virtual ~InputFile() {} void sopen(const char *name, int flags, int shflags); void open(const char *name, int flags) { sopen(name, flags, -1); } @@ -101,7 +100,6 @@ class OutputFile final : public FileBase { public: OutputFile() = default; - virtual ~OutputFile() {} void sopen(const char *name, int flags, int shflags, int mode); void open(const char *name, int flags, int mode) { sopen(name, flags, -1, mode); } diff --git a/src/headers.h b/src/headers.h index d9a1fc93..c5d53954 100644 --- a/src/headers.h +++ b/src/headers.h @@ -91,6 +91,7 @@ static_assert(sizeof(void *) == 8); #endif // C++ system headers +#include #include #include #include diff --git a/src/lefile.cpp b/src/lefile.cpp index a483088f..9ed021c3 100644 --- a/src/lefile.cpp +++ b/src/lefile.cpp @@ -38,7 +38,7 @@ LeFile::LeFile(InputFile *f) : fif(f), fof(nullptr), le_offset(0), exe_offset(0) mem_clear(&oh); } -LeFile::~LeFile() { +LeFile::~LeFile() noexcept { delete[] iobject_table; delete[] oobject_table; delete[] ifpage_table; diff --git a/src/lefile.h b/src/lefile.h index 8d0259a0..41f9b79d 100644 --- a/src/lefile.h +++ b/src/lefile.h @@ -39,7 +39,7 @@ class OutputFile; class LeFile { protected: LeFile(InputFile *); - virtual ~LeFile(); + virtual ~LeFile() noexcept; virtual bool readFileHeader(); virtual void writeFile(OutputFile *, bool); @@ -225,8 +225,8 @@ private: // disable copy and move LeFile(const LeFile &) = delete; LeFile &operator=(const LeFile &) = delete; - LeFile(LeFile &&) = delete; - LeFile &operator=(LeFile &&) = delete; + LeFile(LeFile &&) noexcept = delete; + LeFile &operator=(LeFile &&) noexcept = delete; }; #endif /* already included */ diff --git a/src/main.cpp b/src/main.cpp index 6e37cca6..0dd4ec58 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1317,11 +1317,11 @@ int __acc_cdecl_main main(int argc, char *argv[]) { // srand((int) time(nullptr)); srand((int) clock()); - // info: calling upx_main() here violates implicit "noexcept", so we need a try block + // info: main() is implicitly "noexcept", so we need a try block #if 0 int r = upx_main(argc, argv); #else - int r = EXIT_INTERNAL; + int r; try { r = upx_main(argc, argv); } catch (const Throwable &e) { diff --git a/src/p_w32pe_i386.cpp b/src/p_w32pe_i386.cpp index 95dec62a..363d03d4 100644 --- a/src/p_w32pe_i386.cpp +++ b/src/p_w32pe_i386.cpp @@ -42,7 +42,7 @@ static const CLANG_FORMAT_DUMMY_STATEMENT PackW32PeI386::PackW32PeI386(InputFile *f) : super(f) {} -PackW32PeI386::~PackW32PeI386() {} +PackW32PeI386::~PackW32PeI386() noexcept {} const int *PackW32PeI386::getCompressionMethods(int method, int level) const { bool small = ih.codesize + ih.datasize <= 256 * 1024; diff --git a/src/p_w32pe_i386.h b/src/p_w32pe_i386.h index 751ebf71..7c48e35b 100644 --- a/src/p_w32pe_i386.h +++ b/src/p_w32pe_i386.h @@ -36,7 +36,7 @@ class PackW32PeI386 final : public PeFile32 { public: PackW32PeI386(InputFile *f); - virtual ~PackW32PeI386(); + virtual ~PackW32PeI386() noexcept; virtual int getFormat() const override { return UPX_F_W32PE_I386; } virtual const char *getName() const override { return isrtm ? "rtm32/pe" : "win32/pe"; } virtual const char *getFullName(const Options *) const override { return "i386-win32.pe"; } diff --git a/src/p_w64pe_amd64.cpp b/src/p_w64pe_amd64.cpp index d463b1bb..d8fd797a 100644 --- a/src/p_w64pe_amd64.cpp +++ b/src/p_w64pe_amd64.cpp @@ -47,7 +47,7 @@ static const CLANG_FORMAT_DUMMY_STATEMENT PackW64PeAmd64::PackW64PeAmd64(InputFile *f) : super(f) { use_stub_relocs = false; } -PackW64PeAmd64::~PackW64PeAmd64() {} +PackW64PeAmd64::~PackW64PeAmd64() noexcept {} const int *PackW64PeAmd64::getCompressionMethods(int method, int level) const { bool small = ih.codesize + ih.datasize <= 256 * 1024; diff --git a/src/p_w64pe_amd64.h b/src/p_w64pe_amd64.h index 4ba93276..c2e35fc2 100644 --- a/src/p_w64pe_amd64.h +++ b/src/p_w64pe_amd64.h @@ -36,7 +36,7 @@ class PackW64PeAmd64 final : public PeFile64 { public: PackW64PeAmd64(InputFile *f); - virtual ~PackW64PeAmd64(); + virtual ~PackW64PeAmd64() noexcept; virtual int getFormat() const override { return UPX_F_W64PE_AMD64; } virtual const char *getName() const override { return "win64/pe"; } virtual const char *getFullName(const Options *) const override { return "amd64-win64.pe"; } diff --git a/src/p_w64pe_arm64.h b/src/p_w64pe_arm64.h index 9dfb4509..720ad393 100644 --- a/src/p_w64pe_arm64.h +++ b/src/p_w64pe_arm64.h @@ -36,7 +36,7 @@ class PackW64PeArm64 : public PeFile64 { public: PackW64PeArm64(InputFile *f); - virtual ~PackW64PeArm64() {} + virtual ~PackW64PeArm64() noexcept {} virtual int getFormat() const override { return UPX_F_W64PE_ARM64; } virtual const char *getName() const override { return "win64/arm64"; } virtual const char *getFullName(const Options *) const override { return "arm64-win64.pe"; } diff --git a/src/p_wince_arm.cpp b/src/p_wince_arm.cpp index fb7f7a7b..94aef2b1 100644 --- a/src/p_wince_arm.cpp +++ b/src/p_wince_arm.cpp @@ -44,7 +44,7 @@ static const CLANG_FORMAT_DUMMY_STATEMENT PackWinCeArm::PackWinCeArm(InputFile *f) : super(f) {} -PackWinCeArm::~PackWinCeArm() {} +PackWinCeArm::~PackWinCeArm() noexcept {} Linker *PackWinCeArm::newLinker() const { return new ElfLinkerArmLE; } diff --git a/src/p_wince_arm.h b/src/p_wince_arm.h index b484177f..36fa8850 100644 --- a/src/p_wince_arm.h +++ b/src/p_wince_arm.h @@ -36,7 +36,7 @@ class PackWinCeArm final : public PeFile32 { public: PackWinCeArm(InputFile *f); - virtual ~PackWinCeArm(); + virtual ~PackWinCeArm() noexcept; virtual int getFormat() const override { return UPX_F_WINCE_ARM; } virtual const char *getName() const override { return "wince/arm"; } virtual const char *getFullName(const Options *) const override { return "arm-wince.pe"; } diff --git a/src/packer.h b/src/packer.h index 25177b6b..074064f3 100644 --- a/src/packer.h +++ b/src/packer.h @@ -353,8 +353,8 @@ private: // disable copy and move Packer(const Packer &) = delete; Packer &operator=(const Packer &) = delete; - Packer(Packer &&) = delete; - Packer &operator=(Packer &&) = delete; + Packer(Packer &&) noexcept = delete; + Packer &operator=(Packer &&) noexcept = delete; }; int force_method(int method) noexcept; // (0x80ul<<24)|method diff --git a/src/pefile.cpp b/src/pefile.cpp index 49e843a0..b26f6d78 100644 --- a/src/pefile.cpp +++ b/src/pefile.cpp @@ -215,7 +215,7 @@ int PeFile::readFileHeader() { PeFile::Interval::Interval(void *b) : capacity(0), base(b), ivarr(nullptr), ivnum(0) {} -PeFile::Interval::~Interval() { free(ivarr); } +PeFile::Interval::~Interval() noexcept { free(ivarr); } void PeFile::Interval::add(const void *start, unsigned len) { add(ptr_diff_bytes(start, base), len); @@ -598,7 +598,7 @@ class PeFile::ImportLinker final : public ElfLinkerAMD64 { struct tstr : private ::noncopyable { char *s = nullptr; explicit tstr(char *str) : s(str) {} - ~tstr() { delete[] s; } + ~tstr() noexcept { delete[] s; } operator char *() const { return s; } }; @@ -1069,7 +1069,7 @@ PeFile::Export::Export(char *_base) : base(_base), iv(_base) { size = 0; } -PeFile::Export::~Export() { +PeFile::Export::~Export() noexcept { free(ename); delete[] functionptrs; delete[] ordinals; @@ -1491,7 +1491,7 @@ PeFile::Resource::Resource(const byte *p, const byte *ibufstart_, const byte *ib init(p); } -PeFile::Resource::~Resource() { +PeFile::Resource::~Resource() noexcept { if (root) { destroy(root, 0); root = nullptr; @@ -1670,7 +1670,7 @@ byte *PeFile::Resource::build() { return newstart; } -void PeFile::Resource::destroy(upx_rnode *node, unsigned level) { +void PeFile::Resource::destroy(upx_rnode *node, unsigned level) noexcept { xcheck(node); if (level == 3) { upx_rleaf *leaf = ACC_STATIC_CAST(upx_rleaf *, node); @@ -2974,7 +2974,7 @@ upx_uint64_t PeFile::ilinkerGetAddress(const char *d, const char *n) const { return ilinker->getAddress(d, n); } -PeFile::~PeFile() { +PeFile::~PeFile() noexcept { oimpdlls = nullptr; delete[] oxrelocs; delete ilinker; @@ -2993,7 +2993,7 @@ PeFile32::PeFile32(InputFile *f) : super(f) { oddirs = oh.ddirs; } -PeFile32::~PeFile32() {} +PeFile32::~PeFile32() noexcept {} void PeFile32::readPeHeader() { fi->readx(&ih, sizeof(ih)); @@ -3046,7 +3046,7 @@ PeFile64::PeFile64(InputFile *f) : super(f) { oddirs = oh.ddirs; } -PeFile64::~PeFile64() {} +PeFile64::~PeFile64() noexcept {} void PeFile64::readPeHeader() { fi->readx(&ih, sizeof(ih)); diff --git a/src/pefile.h b/src/pefile.h index 9cdccdda..9d1005a6 100644 --- a/src/pefile.h +++ b/src/pefile.h @@ -46,7 +46,7 @@ protected: struct pe_section_t; PeFile(InputFile *f); - virtual ~PeFile(); + virtual ~PeFile() noexcept; void readSectionHeaders(unsigned objs, unsigned sizeof_ih); unsigned readSections(unsigned objs, unsigned usize, unsigned ih_filealign, @@ -371,7 +371,7 @@ protected: unsigned ivnum; Interval(void *b); - ~Interval(); + ~Interval() noexcept; void add(unsigned start, unsigned len); void add(const void *start, unsigned len); @@ -433,14 +433,14 @@ protected: void build(const upx_rnode *, unsigned &, unsigned &, unsigned); void clear(byte *, unsigned, Interval *); void dump(const upx_rnode *, unsigned) const; - void destroy(upx_rnode *urd, unsigned level); + void destroy(upx_rnode *urd, unsigned level) noexcept; void ibufcheck(const void *m, unsigned size); public: Resource(const byte *ibufstart, const byte *ibufen); Resource(const byte *p, const byte *ibufstart, const byte *ibufend); - ~Resource(); + ~Resource() noexcept; void init(const byte *); unsigned dirsize() const; @@ -488,7 +488,7 @@ protected: public: Export(char *_base); - ~Export(); + ~Export() noexcept; void convert(unsigned eoffs, unsigned esize); void build(char *base, unsigned newoffs); @@ -500,7 +500,7 @@ class PeFile32 : public PeFile { typedef PeFile super; protected: PeFile32(InputFile *f); - virtual ~PeFile32(); + virtual ~PeFile32() noexcept; void pack0(OutputFile *fo, unsigned subsystem_mask, upx_uint64_t default_imagebase, bool last_section_rsrc_only); @@ -561,7 +561,7 @@ class PeFile64 : public PeFile { typedef PeFile super; protected: PeFile64(InputFile *f); - virtual ~PeFile64(); + virtual ~PeFile64() noexcept; void pack0(OutputFile *fo, unsigned subsystem_mask, upx_uint64_t default_imagebase); diff --git a/src/util/membuffer.h b/src/util/membuffer.h index 4f77f4f9..5fefbc0e 100644 --- a/src/util/membuffer.h +++ b/src/util/membuffer.h @@ -49,7 +49,7 @@ protected: public: inline MemBufferBase() noexcept : ptr(nullptr), size_in_bytes(0) {} - inline ~MemBufferBase() noexcept {} + forceinline ~MemBufferBase() noexcept {} // IMPORTANT NOTE: automatic conversion to underlying pointer // HINT: for fully bound-checked pointer use XSPAN_S from xspan.h @@ -213,8 +213,8 @@ private: MemBuffer(const MemBuffer &) DELETED_FUNCTION; MemBuffer &operator=(const MemBuffer &) DELETED_FUNCTION; #if __cplusplus >= 201103L - MemBuffer(MemBuffer &&) DELETED_FUNCTION; - MemBuffer &operator=(MemBuffer &&) DELETED_FUNCTION; + MemBuffer(MemBuffer &&) noexcept DELETED_FUNCTION; + MemBuffer &operator=(MemBuffer &&) noexcept DELETED_FUNCTION; #endif // disable dynamic allocation ACC_CXX_DISABLE_NEW_DELETE diff --git a/src/util/util.cpp b/src/util/util.cpp index f3c08470..afaf2948 100644 --- a/src/util/util.cpp +++ b/src/util/util.cpp @@ -27,8 +27,6 @@ #include "../headers.h" #include -#include "../conf.h" - #define ACC_WANT_ACC_INCI_H 1 #include "../miniacc.h" #define ACC_WANT_ACCLIB_GETOPT 1 @@ -38,6 +36,7 @@ #define ACC_WANT_ACCLIB_WILDARGV 1 #undef HAVE_MKDIR #include "../miniacc.h" +#include "../conf.h" /************************************************************************* // assert sane memory buffer sizes to protect against integer overflows diff --git a/src/util/xspan_impl_common.h b/src/util/xspan_impl_common.h index 16479e38..31caa7e2 100644 --- a/src/util/xspan_impl_common.h +++ b/src/util/xspan_impl_common.h @@ -101,7 +101,13 @@ forceinline void assertInvariants() const noexcept {} public: #if DEBUG - inline ~CSelf() { invalidate(); } + ~CSelf() noexcept { + try { + invalidate(); + } catch (...) { + std::terminate(); + } + } #else forceinline ~CSelf() noexcept {} #endif diff --git a/src/util/xspan_impl_ptr.h b/src/util/xspan_impl_ptr.h index 758b299d..ad8f63d2 100644 --- a/src/util/xspan_impl_ptr.h +++ b/src/util/xspan_impl_ptr.h @@ -63,9 +63,15 @@ public: #endif #if DEBUG - inline ~CSelf() { invalidate(); } + ~CSelf() noexcept { + try { + invalidate(); + } catch (...) { + std::terminate(); + } + } #else - inline ~CSelf() noexcept {} + forceinline ~CSelf() noexcept {} #endif noinline void invalidate() { assertInvariants();