Merge pull request #85954 from jckarter/sil-require-require-instruction

SIL verifier: The `atInstruction`/`atArgument` parameter to `require` should not be optional.
This commit is contained in:
Joe Groff
2025-12-11 09:43:43 -08:00
committed by GitHub
3 changed files with 42 additions and 19 deletions

View File

@@ -18,7 +18,7 @@ private protocol VerifiableInstruction : Instruction {
func verify(_ context: VerifierContext) func verify(_ context: VerifierContext)
} }
private func require(_ condition: Bool, _ message: @autoclosure () -> String, atInstruction: Instruction? = nil) { private func require(_ condition: Bool, _ message: @autoclosure () -> String, atInstruction: Instruction) {
if !condition { if !condition {
let msg = message() let msg = message()
msg._withBridgedStringRef { stringRef in msg._withBridgedStringRef { stringRef in
@@ -27,6 +27,15 @@ private func require(_ condition: Bool, _ message: @autoclosure () -> String, at
} }
} }
private func require(_ condition: Bool, _ message: @autoclosure () -> String, atArgument: Argument) {
if !condition {
let msg = message()
msg._withBridgedStringRef { stringRef in
BridgedVerifier.verifierError(stringRef, atArgument.bridged)
}
}
}
struct VerifierContext: Context { struct VerifierContext: Context {
let _bridged: BridgedContext let _bridged: BridgedContext
} }
@@ -53,16 +62,21 @@ extension Function {
private extension Instruction { private extension Instruction {
func checkForwardingConformance() { func checkForwardingConformance() {
if bridged.shouldBeForwarding() { if bridged.shouldBeForwarding() {
require(self is ForwardingInstruction, "instruction \(self)\nshould conform to ForwardingInstruction") require(self is ForwardingInstruction,
"instruction \(self)\nshould conform to ForwardingInstruction",
atInstruction: self)
} else { } else {
require(!(self is ForwardingInstruction), "instruction \(self)\nshould not conform to ForwardingInstruction") require(!(self is ForwardingInstruction),
"instruction \(self)\nshould not conform to ForwardingInstruction",
atInstruction: self)
} }
} }
func checkGuaranteedResults() { func checkGuaranteedResults() {
for result in results where result.ownership == .guaranteed { for result in results where result.ownership == .guaranteed {
require(BeginBorrowValue(result) != nil || self is ForwardingInstruction || result.isGuaranteedApplyResult, require(BeginBorrowValue(result) != nil || self is ForwardingInstruction || result.isGuaranteedApplyResult,
"\(result) must either be a BeginBorrowValue or a ForwardingInstruction") "\(result) must either be a BeginBorrowValue or a ForwardingInstruction",
atInstruction: self)
} }
} }
} }
@@ -89,14 +103,17 @@ private extension Phi {
var forwardingBorrowedFromFound = false var forwardingBorrowedFromFound = false
for use in value.uses { for use in value.uses {
require(use.instruction is BorrowedFromInst, require(use.instruction is BorrowedFromInst,
"guaranteed phi: \(self)\n has non borrowed-from use: \(use)") "guaranteed phi: \(self)\n has non borrowed-from use: \(use)",
atArgument: self.value)
if use.index == 0 { if use.index == 0 {
require(!forwardingBorrowedFromFound, "phi \(self) has multiple forwarding borrowed-from uses") require(!forwardingBorrowedFromFound, "phi \(self) has multiple forwarding borrowed-from uses",
atArgument: self.value)
forwardingBorrowedFromFound = true forwardingBorrowedFromFound = true
} }
} }
require(forwardingBorrowedFromFound, require(forwardingBorrowedFromFound,
"missing forwarding borrowed-from user of guaranteed phi \(self)") "missing forwarding borrowed-from user of guaranteed phi \(self)",
atArgument: self.value)
} }
} }
@@ -104,7 +121,9 @@ extension BorrowedFromInst : VerifiableInstruction {
func verify(_ context: VerifierContext) { func verify(_ context: VerifierContext) {
for ev in enclosingValues { for ev in enclosingValues {
require(ev.isValidEnclosingValueInBorrowedFrom, "invalid enclosing value in borrowed-from: \(ev)") require(ev.isValidEnclosingValueInBorrowedFrom,
"invalid enclosing value in borrowed-from: \(ev)",
atInstruction: self)
} }
var computedEVs = Stack<Value>(context) var computedEVs = Stack<Value>(context)
@@ -120,7 +139,8 @@ extension BorrowedFromInst : VerifiableInstruction {
for computedEV in computedEVs { for computedEV in computedEVs {
require(existingEVs.contains(computedEV), require(existingEVs.contains(computedEV),
"\(computedEV)\n missing in enclosing values of \(self)") "\(computedEV)\n missing in enclosing values of \(self)",
atInstruction: self)
} }
} }
} }
@@ -189,10 +209,12 @@ extension BeginAccessInst : VerifiableInstruction {
extension VectorBaseAddrInst : VerifiableInstruction { extension VectorBaseAddrInst : VerifiableInstruction {
func verify(_ context: VerifierContext) { func verify(_ context: VerifierContext) {
require(vector.type.isBuiltinFixedArray, require(vector.type.isBuiltinFixedArray,
"vector operand of vector_element_addr must be a Builtin.FixedArray") "vector operand of vector_element_addr must be a Builtin.FixedArray",
atInstruction: self)
require(type == vector.type.builtinFixedArrayElementType(in: parentFunction, require(type == vector.type.builtinFixedArrayElementType(in: parentFunction,
maximallyAbstracted: true).addressType, maximallyAbstracted: true).addressType,
"result of vector_element_addr has wrong type") "result of vector_element_addr has wrong type",
atInstruction: self)
} }
} }
@@ -235,7 +257,8 @@ private struct MutatingUsesWalker : AddressDefUseWalker {
if let bf = phi.borrowedFrom { if let bf = phi.borrowedFrom {
linearLiveranges.pushIfNotVisited(bf) linearLiveranges.pushIfNotVisited(bf)
} else { } else {
require(false, "missing borrowed-from for \(phi.value)") require(false, "missing borrowed-from for \(phi.value)",
atArgument: phi.value)
} }
} }
} }

View File

@@ -1629,11 +1629,11 @@ struct BridgedVerifier {
static void registerVerifier(VerifyFunctionFn verifyFunctionFn); static void registerVerifier(VerifyFunctionFn verifyFunctionFn);
static void verifierError(BridgedStringRef message, static void verifierError(BridgedStringRef message,
OptionalBridgedInstruction atInstruction); BridgedInstruction atInstruction);
static void verifierError(BridgedStringRef message, static void verifierError(BridgedStringRef message,
OptionalBridgedArgument atArgument); BridgedArgument atArgument);
static void verifierError(BridgedStringRef message, static void verifierError(BridgedStringRef message,
OptionalBridgedValue atValue); BridgedValue atValue);
}; };
struct BridgedUtilities { struct BridgedUtilities {

View File

@@ -918,19 +918,19 @@ void BridgedVerifier::runSwiftFunctionVerification(SILFunction * _Nonnull f, SIL
} }
void BridgedVerifier::verifierError(BridgedStringRef message, void BridgedVerifier::verifierError(BridgedStringRef message,
OptionalBridgedInstruction atInstruction) { BridgedInstruction atInstruction) {
verificationFailure(message.unbridged(), atInstruction.unbridged(), verificationFailure(message.unbridged(), atInstruction.unbridged(),
/*extraContext=*/nullptr); /*extraContext=*/nullptr);
} }
void BridgedVerifier::verifierError(BridgedStringRef message, void BridgedVerifier::verifierError(BridgedStringRef message,
OptionalBridgedArgument atArgument) { BridgedArgument atArgument) {
verificationFailure(message.unbridged(), atArgument.unbridged(), verificationFailure(message.unbridged(), atArgument.getArgument(),
/*extraContext=*/nullptr); /*extraContext=*/nullptr);
} }
void BridgedVerifier::verifierError(BridgedStringRef message, void BridgedVerifier::verifierError(BridgedStringRef message,
OptionalBridgedValue atValue) { BridgedValue atValue) {
verificationFailure(message.unbridged(), SILValue(atValue.getSILValue()), verificationFailure(message.unbridged(), SILValue(atValue.getSILValue()),
/*extraContext=*/nullptr); /*extraContext=*/nullptr);
} }