mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This adds three new assertion macros: * `ASSERT` - always compiled in, always checked * `CONDITIONAL_ASSERT` - always compiled in, checked whenever the `-compiler-assertions` flag is provided * `DEBUG_ASSERT` - only compiled into debug builds, always checked when compiled in (functionally the same as Standard C `assert`) The new `-compiler-assertions` flag is recognized by both `swift-frontend` and `swiftc`. The goal is to eventually replace every use of `assert` in the compiler with one of the above: * Most assertions will use `ASSERT` (most assertions should always be present and checked, even in release builds) * Expensive assertions can use `CONDITIONAL_ASSERT` to be suppressed by default * A few very expensive and/or brittle assertions can use `DEBUG_ASSERT` to be compiled out of release builds This should: * Improve quality by catching errors earlier, * Accelerate compiler triage and debugging by providing more accurate crash dumps by default, and * Allow compiler engineers and end users alike to add `-compiler-assertions` to get more accurate failure diagnostics with any compiler
56 lines
1.7 KiB
C++
56 lines
1.7 KiB
C++
//===--- Assertions.cpp - Swift Version Number -------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2023 - 2023 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defines custom assertion support functions
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "swift/Basic/Assertions.h"
|
|
#undef NDEBUG
|
|
#include <cassert>
|
|
#include <iostream>
|
|
|
|
int CONDITIONAL_ASSERT_Global_enable_flag =
|
|
#ifdef NDEBUG
|
|
0; // Default to `off` in release builds
|
|
#else
|
|
0; // TODO: Default to `on` in debug builds
|
|
#endif
|
|
|
|
[[noreturn]] void ASSERT_failure(const char *expr, const char *file, int line, const char *func) {
|
|
// Only print the last component of `file`
|
|
const char *f = file;
|
|
for (const char *p = file; *p != '\0'; p++) {
|
|
if ((p[0] == '/' || p[0] == '\\')
|
|
&& p[1] != '/' && p[1] != '\\' && p[1] != '\0') {
|
|
f = p + 1;
|
|
}
|
|
}
|
|
// Format here matches that used by `assert` on macOS:
|
|
std::cerr
|
|
<< "Assertion failed: "
|
|
<< "(" << expr << "), "
|
|
<< "function " << func << ", "
|
|
<< "file " << f << ", "
|
|
<< "line " << line << "."
|
|
<< std::endl;
|
|
abort();
|
|
}
|
|
|
|
// This has to be callable in the same way as the macro version,
|
|
// so we can't put it inside a namespace.
|
|
#undef CONDITIONAL_ASSERT_enabled
|
|
int CONDITIONAL_ASSERT_enabled() {
|
|
return (CONDITIONAL_ASSERT_Global_enable_flag != 0);
|
|
}
|
|
|