Skip to content

Some assertion improvements #74685

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 22 additions & 6 deletions SwiftCompilerSources/Sources/Basic/Utils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,36 @@
/// case for `precondition`.
@_transparent
public func assert(_ condition: Bool, _ message: @autoclosure () -> String,
file: StaticString = #fileID, line: UInt = #line) {
if !condition {
fatalError(message(), file: file, line: line)
}
file: StaticString = #fileID, line: UInt = #line, function: StaticString = #function) {
precondition(condition, message(), file: file, line: line, function: function)
}

/// The assert function (without a message) to be used in the compiler.
///
/// Unforuntately it's not possible to just add a default argument to `message` in the
/// other `assert` function. We need to defined this overload.
/// TODO: For some reason the compiler is not happy when adding a `function` argument.
@_transparent
public func assert(_ condition: Bool, file: StaticString = #fileID, line: UInt = #line) {
if !condition {
fatalError("", file: file, line: line)
precondition(condition, "", file: file, line: line, function: "")
}

/// The assert function to be used in the compiler.
///
/// This overrides the standard Swift precondition and forwards an assertion failure
/// to the assertion-handling in the C++ code base.
@_transparent
public func precondition(_ condition: Bool, _ message: @autoclosure () -> String,
file: StaticString = #fileID, line: UInt = #line, function: StaticString = #function) {
if !_fastPath(condition) {
let msg = message()
msg.withCString { msgStr in
file.withUTF8Buffer { fileBytes in
function.withUTF8Buffer { functionBytes in
assertFail(msgStr, fileBytes.baseAddress!, line, functionBytes.baseAddress!)
}
}
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions include/swift/Basic/BasicBridging.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ typedef uintptr_t SwiftUInt;
#define BRIDGING_WRAPPER_NULLABLE(Node, Name) \
BRIDGING_WRAPPER_IMPL(Node, Nullable##Name, _Nullable)

void assertFail(const char * _Nonnull msg, const char * _Nonnull file,
SwiftUInt line, const char * _Nonnull function);

//===----------------------------------------------------------------------===//
// MARK: ArrayRef
//===----------------------------------------------------------------------===//
Expand Down
38 changes: 0 additions & 38 deletions include/swift/Basic/Require.h

This file was deleted.

12 changes: 6 additions & 6 deletions include/swift/SIL/SILBitfield.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#ifndef SWIFT_SIL_SILBITFIELD_H
#define SWIFT_SIL_SILBITFIELD_H

#include "swift/Basic/Require.h"
#include "swift/Basic/Assertions.h"
#include "swift/SIL/SILFunction.h"

namespace swift {
Expand Down Expand Up @@ -56,12 +56,12 @@ template <class Impl, class T> class SILBitfield {
parent(parent),
function(function) {
assert(size > 0 && "bit field size must be > 0");
require(endBit <= T::numCustomBits,
"too many/large bit fields allocated in function");
assert((!parent || bitfieldID > parent->bitfieldID) &&
ASSERT(endBit <= T::numCustomBits &&
"too many/large bit fields allocated in function");
ASSERT((!parent || bitfieldID > parent->bitfieldID) &&
"BasicBlockBitfield indices are not in order");
require(function->currentBitfieldID < T::maxBitfieldID,
"currentBitfieldID overflow");
ASSERT(function->currentBitfieldID < T::maxBitfieldID &&
"currentBitfieldID overflow");
++function->currentBitfieldID;
}

Expand Down
14 changes: 7 additions & 7 deletions lib/Basic/Assertions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,6 @@ int CONDITIONAL_ASSERT_Global_enable_flag =
#endif

void ASSERT_failure(const char *expr, const char *filename, int line, const char *func) {
if (AssertHelp) {
ASSERT_help();
} else {
llvm::errs() << "Assertion help: -Xllvm -assert-help\n";
}


// Format here matches that used by `assert` on macOS:
llvm::errs()
<< "Assertion failed: "
Expand All @@ -52,6 +45,8 @@ void ASSERT_failure(const char *expr, const char *filename, int line, const char
<< filename << ":"
<< line << ".\n";

ASSERT_help();

if (AssertContinue) {
llvm::errs() << "Continuing after failed assertion (-Xllvm -assert-continue)\n";
return;
Expand All @@ -67,6 +62,11 @@ void ASSERT_help() {
}
ASSERT_help_shown = 1;

if (!AssertHelp) {
llvm::errs() << "(to display assertion configuration options: -Xllvm -assert-help)\n";
return;
}

llvm::errs() << "\n";
llvm::errs() << "Control assertion behavior with one or more of the following options:\n\n";
llvm::errs() << " -Xllvm -assert-continue\n";
Expand Down
6 changes: 6 additions & 0 deletions lib/Basic/BasicBridging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
//
//===----------------------------------------------------------------------===//

#include "swift/Basic/Assertions.h"
#include "swift/Basic/BasicBridging.h"
#include "llvm/Support/JSON.h"
#include "llvm/Support/raw_ostream.h"
Expand All @@ -22,6 +23,11 @@

using namespace swift;

void assertFail(const char * _Nonnull msg, const char * _Nonnull file,
SwiftUInt line, const char * _Nonnull function) {
ASSERT_failure(msg, file, line, function);
}

//===----------------------------------------------------------------------===//
// MARK: BridgedStringRef
//===----------------------------------------------------------------------===//
Expand Down
15 changes: 7 additions & 8 deletions lib/SIL/IR/Linker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@
#include "swift/AST/ProtocolConformance.h"
#include "swift/AST/SubstitutionMap.h"
#include "swift/Basic/Assertions.h"
#include "swift/Basic/Require.h"
#include "swift/ClangImporter/ClangModule.h"
#include "swift/SIL/FormalLinkage.h"
#include "swift/Serialization/SerializedSILLoader.h"
Expand All @@ -76,20 +75,20 @@ STATISTIC(NumFuncLinked, "Number of SIL functions linked");
//===----------------------------------------------------------------------===//

void SILLinkerVisitor::deserializeAndPushToWorklist(SILFunction *F) {
assert(F->isExternalDeclaration());
ASSERT(F->isExternalDeclaration());

LLVM_DEBUG(llvm::dbgs() << "Imported function: "
<< F->getName() << "\n");
SILFunction *NewF =
Mod.getSILLoader()->lookupSILFunction(F, /*onlyUpdateLinkage*/ false);
assert(!NewF || NewF == F);
ASSERT(!NewF || NewF == F);
if (!NewF || F->isExternalDeclaration()) {
assert((!hasSharedVisibility(F->getLinkage()) || F->hasForeignBody()) &&
ASSERT((!hasSharedVisibility(F->getLinkage()) || F->hasForeignBody()) &&
"cannot deserialize shared function");
return;
}

assert(!F->isAnySerialized() == Mod.isSerialized() &&
ASSERT(!F->isAnySerialized() == Mod.isSerialized() &&
"the de-serializer did set the wrong serialized flag");

F->setBare(IsBare);
Expand All @@ -103,9 +102,9 @@ void SILLinkerVisitor::deserializeAndPushToWorklist(SILFunction *F) {
void SILLinkerVisitor::maybeAddFunctionToWorklist(
SILFunction *F, SerializedKind_t callerSerializedKind) {
SILLinkage linkage = F->getLinkage();
require(callerSerializedKind == IsNotSerialized ||
ASSERT((callerSerializedKind == IsNotSerialized ||
F->hasValidLinkageForFragileRef(callerSerializedKind) ||
hasSharedVisibility(linkage) || F->isExternForwardDeclaration(),
hasSharedVisibility(linkage) || F->isExternForwardDeclaration()) &&
"called function has wrong linkage for serialized function");
if (!F->isExternalDeclaration()) {
// The function is already in the module, so no need to de-serialized it.
Expand Down Expand Up @@ -175,7 +174,7 @@ void SILLinkerVisitor::linkInVTable(ClassDecl *D) {
// vtables that might have shared linkage yet, so this is only needed in
// the performance pipeline to deserialize more functions early, and expose
// optimization opportunities.
assert(isLinkAll());
ASSERT(isLinkAll());

// Attempt to lookup the Vtbl from the SILModule.
SILVTable *Vtbl = Mod.lookUpVTable(D);
Expand Down
12 changes: 6 additions & 6 deletions lib/SILOptimizer/PassManager/PassManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1422,8 +1422,8 @@ FixedSizeSlab *SwiftPassInvocation::freeSlab(FixedSizeSlab *slab) {
}

BasicBlockSet *SwiftPassInvocation::allocBlockSet() {
require(numBlockSetsAllocated < BlockSetCapacity,
"too many BasicBlockSets allocated");
ASSERT(numBlockSetsAllocated < BlockSetCapacity &&
"too many BasicBlockSets allocated");

auto *storage = (BasicBlockSet *)blockSetStorage + numBlockSetsAllocated;
BasicBlockSet *set = new (storage) BasicBlockSet(function);
Expand All @@ -1446,8 +1446,8 @@ void SwiftPassInvocation::freeBlockSet(BasicBlockSet *set) {
}

NodeSet *SwiftPassInvocation::allocNodeSet() {
require(numNodeSetsAllocated < NodeSetCapacity,
"too many NodeSets allocated");
ASSERT(numNodeSetsAllocated < NodeSetCapacity &&
"too many NodeSets allocated");

auto *storage = (NodeSet *)nodeSetStorage + numNodeSetsAllocated;
NodeSet *set = new (storage) NodeSet(function);
Expand All @@ -1470,8 +1470,8 @@ void SwiftPassInvocation::freeNodeSet(NodeSet *set) {
}

OperandSet *SwiftPassInvocation::allocOperandSet() {
require(numOperandSetsAllocated < OperandSetCapacity,
"too many OperandSets allocated");
ASSERT(numOperandSetsAllocated < OperandSetCapacity &&
"too many OperandSets allocated");

auto *storage = (OperandSet *)operandSetStorage + numOperandSetsAllocated;
OperandSet *set = new (storage) OperandSet(function);
Expand Down
5 changes: 2 additions & 3 deletions lib/SILOptimizer/Utils/PerformanceInlinerUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#include "swift/SILOptimizer/Utils/PerformanceInlinerUtils.h"
#include "swift/AST/Module.h"
#include "swift/Basic/Assertions.h"
#include "swift/Basic/Require.h"
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
#include "llvm/Support/CommandLine.h"

Expand Down Expand Up @@ -853,8 +852,8 @@ SILFunction *swift::getEligibleFunction(FullApplySite AI,
!Callee->hasValidLinkageForFragileRef(Caller->getSerializedKind())) {
llvm::errs() << "caller: " << Caller->getName() << "\n";
llvm::errs() << "callee: " << Callee->getName() << "\n";
require(false, "Should never be inlining a resilient function into "
"a fragile function");
ASSERT(false && "Should never be inlining a resilient function into "
"a fragile function");
}
return nullptr;
}
Expand Down