mirror of
https://github.com/apple/swift.git
synced 2026-02-27 18:26:24 +01:00
FrontendTool: Stop if SILGen emits diagnostics even when lazy type checking is off
We've had several bugs lately where SILGen produces a diagnostic, but the resulting invalid SIL causes crashes further down in the mandatory pipeline. To prevent this from happening, just stop after SILGen if diagnostics were emitted, even if lazy type checking is disabled, because the same rationale applies in either case.
This commit is contained in:
@@ -2053,11 +2053,11 @@ static bool performCompileStepsPostSILGen(
|
||||
return writeSIL(*SM, PSPs, Instance, Invocation.getSILOptions());
|
||||
}
|
||||
|
||||
// In lazy typechecking mode, SILGen may have triggered requests which
|
||||
// resulted in errors. We don't want to proceed with optimization or
|
||||
// serialization if there were errors since the SIL may be incomplete or
|
||||
// invalid.
|
||||
if (Context.TypeCheckerOpts.EnableLazyTypecheck && Context.hadError())
|
||||
// SILGen emits certain diagnostics of its own, and it can also trigger
|
||||
// requests which result in errors. We don't want to proceed with
|
||||
// optimization or serialization if there were errors since the SIL
|
||||
// may be incomplete or invalid.
|
||||
if (!Context.LangOpts.AllowModuleWithCompilerErrors && Context.hadError())
|
||||
return true;
|
||||
|
||||
if (Action == FrontendOptions::ActionType::EmitSIBGen) {
|
||||
|
||||
46
test/SILGen/exclusivity_static_diagnostics.swift
Normal file
46
test/SILGen/exclusivity_static_diagnostics.swift
Normal file
@@ -0,0 +1,46 @@
|
||||
// RUN: %target-swift-frontend -enforce-exclusivity=checked -swift-version 4 -emit-sil -primary-file %s -o /dev/null -verify
|
||||
|
||||
import Swift
|
||||
|
||||
func takesTwoInouts<T>(_ p1: inout T, _ p2: inout T) { }
|
||||
|
||||
func simpleInoutDiagnostic() {
|
||||
var i = 7
|
||||
|
||||
// FIXME: This diagnostic should be removed if static enforcement is
|
||||
// turned on by default.
|
||||
// expected-error@+2{{inout arguments are not allowed to alias each other}}
|
||||
// expected-note@+1{{previous aliasing argument}}
|
||||
takesTwoInouts(&i, &i)
|
||||
}
|
||||
|
||||
func inoutOnInoutParameter(p: inout Int) {
|
||||
// expected-error@+2{{inout arguments are not allowed to alias each other}}
|
||||
// expected-note@+1{{previous aliasing argument}}
|
||||
takesTwoInouts(&p, &p)
|
||||
}
|
||||
|
||||
class SomeClass { }
|
||||
|
||||
struct StructWithMutatingMethodThatTakesSelfInout {
|
||||
var f = SomeClass()
|
||||
mutating func mutate(_ other: inout StructWithMutatingMethodThatTakesSelfInout) { }
|
||||
mutating func mutate(_ other: inout SomeClass) { }
|
||||
|
||||
mutating func callMutatingMethodThatTakesSelfInout() {
|
||||
// expected-error@+2{{inout arguments are not allowed to alias each other}}
|
||||
// expected-note@+1{{previous aliasing argument}}
|
||||
mutate(&self)
|
||||
}
|
||||
|
||||
mutating func callMutatingMethodThatTakesSelfStoredPropInout() {
|
||||
mutate(&self.f)
|
||||
}
|
||||
}
|
||||
|
||||
func violationWithGenericType<T>(_ p: T) {
|
||||
var local = p
|
||||
// expected-error@+2{{inout arguments are not allowed to alias each other}}
|
||||
// expected-note@+1{{previous aliasing argument}}
|
||||
takesTwoInouts(&local, &local)
|
||||
}
|
||||
13
test/SILGen/noimplicitcopy_diagnostic.swift
Normal file
13
test/SILGen/noimplicitcopy_diagnostic.swift
Normal file
@@ -0,0 +1,13 @@
|
||||
// RUN: %target-swift-frontend -enable-experimental-move-only -verify %s -emit-silgen
|
||||
|
||||
func useValue<T>(_ x: T) {}
|
||||
func consumeValue<T>(_ x: __owned T) {}
|
||||
|
||||
struct GenericAggregate<T> {
|
||||
var value: T
|
||||
}
|
||||
|
||||
func test1<T>(_ x: T) {
|
||||
@_noImplicitCopy let x2 = x // expected-error {{'@_noImplicitCopy' can not be used on a generic or existential typed binding or a nominal type containing such typed things}}
|
||||
_ = x2
|
||||
}
|
||||
@@ -1,31 +1,14 @@
|
||||
// RUN: %target-swift-emit-sil -verify %s
|
||||
// RUN: %target-swift-frontend -emit-sil -verify %s
|
||||
// RUN: %target-swift-emit-silgen -verify %s
|
||||
|
||||
struct Block {}
|
||||
|
||||
class Story {
|
||||
final var finalStored = [Block]()
|
||||
var overridableStored = [Block]()
|
||||
var computed: [Block] {
|
||||
get { return [] }
|
||||
set {}
|
||||
}
|
||||
|
||||
func test() {
|
||||
// expected-error@+2 {{overlapping accesses to 'finalStored', but modification requires exclusive access; consider calling MutableCollection.swapAt(_:_:)}}
|
||||
// expected-note@+1 {{conflicting access is here}}
|
||||
swap(&self.finalStored[0], &self.finalStored[1])
|
||||
swap(&self.overridableStored[0], &self.overridableStored[1])
|
||||
swap(&self.computed[0], &self.computed[1]) // expected-error{{invalid aliasing}} expected-note{{concurrent writeback}}
|
||||
}
|
||||
}
|
||||
|
||||
protocol Storied {
|
||||
var protocolRequirement: [Block] { get set }
|
||||
}
|
||||
|
||||
func testProtocol<T: Storied>(x: inout T) {
|
||||
// expected-error@+2 {{overlapping accesses to 'x', but modification requires exclusive access; consider calling MutableCollection.swapAt(_:_:)}}
|
||||
// expected-note@+1 {{conflicting access is here}}
|
||||
swap(&x.protocolRequirement[0], &x.protocolRequirement[1])
|
||||
}
|
||||
|
||||
@@ -4,26 +4,6 @@ import Swift
|
||||
|
||||
func takesTwoInouts<T>(_ p1: inout T, _ p2: inout T) { }
|
||||
|
||||
func simpleInoutDiagnostic() {
|
||||
var i = 7
|
||||
|
||||
// FIXME: This diagnostic should be removed if static enforcement is
|
||||
// turned on by default.
|
||||
// expected-error@+4{{inout arguments are not allowed to alias each other}}
|
||||
// expected-note@+3{{previous aliasing argument}}
|
||||
// expected-error@+2{{overlapping accesses to 'i', but modification requires exclusive access; consider copying to a local variable}}
|
||||
// expected-note@+1{{conflicting access is here}}
|
||||
takesTwoInouts(&i, &i)
|
||||
}
|
||||
|
||||
func inoutOnInoutParameter(p: inout Int) {
|
||||
// expected-error@+4{{inout arguments are not allowed to alias each other}}
|
||||
// expected-note@+3{{previous aliasing argument}}
|
||||
// expected-error@+2{{overlapping accesses to 'p', but modification requires exclusive access; consider copying to a local variable}}
|
||||
// expected-note@+1{{conflicting access is here}}
|
||||
takesTwoInouts(&p, &p)
|
||||
}
|
||||
|
||||
func swapNoSuppression(_ i: Int, _ j: Int) {
|
||||
var a: [Int] = [1, 2, 3]
|
||||
|
||||
@@ -39,14 +19,6 @@ struct StructWithMutatingMethodThatTakesSelfInout {
|
||||
mutating func mutate(_ other: inout StructWithMutatingMethodThatTakesSelfInout) { }
|
||||
mutating func mutate(_ other: inout SomeClass) { }
|
||||
|
||||
mutating func callMutatingMethodThatTakesSelfInout() {
|
||||
// expected-error@+4{{inout arguments are not allowed to alias each other}}
|
||||
// expected-note@+3{{previous aliasing argument}}
|
||||
// expected-error@+2{{overlapping accesses to 'self', but modification requires exclusive access; consider copying to a local variable}}
|
||||
// expected-note@+1{{conflicting access is here}}
|
||||
mutate(&self)
|
||||
}
|
||||
|
||||
mutating func callMutatingMethodThatTakesSelfStoredPropInout() {
|
||||
// expected-error@+2{{overlapping accesses to 'self', but modification requires exclusive access; consider copying to a local variable}}
|
||||
// expected-note@+1{{conflicting access is here}}
|
||||
@@ -81,16 +53,6 @@ class ClassWithFinalStoredProp {
|
||||
}
|
||||
}
|
||||
|
||||
func violationWithGenericType<T>(_ p: T) {
|
||||
var local = p
|
||||
// expected-error@+4{{inout arguments are not allowed to alias each other}}
|
||||
// expected-note@+3{{previous aliasing argument}}
|
||||
// expected-error@+2{{overlapping accesses to 'local', but modification requires exclusive access; consider copying to a local variable}}
|
||||
// expected-note@+1{{conflicting access is here}}
|
||||
takesTwoInouts(&local, &local)
|
||||
}
|
||||
|
||||
|
||||
// Helper.
|
||||
struct StructWithTwoStoredProp {
|
||||
var f1: Int = 7
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// RUN: %target-swift-frontend -enable-experimental-move-only -verify %s -emit-sil
|
||||
|
||||
// REQUIRES: rdar168066916
|
||||
|
||||
func useValue<T>(_ x: T) {}
|
||||
func consumeValue<T>(_ x: __owned T) {}
|
||||
|
||||
|
||||
15
test/SILOptimizer/polymorphic_inout_aliasing.swift
Normal file
15
test/SILOptimizer/polymorphic_inout_aliasing.swift
Normal file
@@ -0,0 +1,15 @@
|
||||
// RUN: %target-swift-emit-sil -verify %s
|
||||
|
||||
struct Block {}
|
||||
|
||||
class Story {
|
||||
final var finalStored = [Block]()
|
||||
var overridableStored = [Block]()
|
||||
|
||||
func test() {
|
||||
// expected-error@+2 {{overlapping accesses to 'finalStored', but modification requires exclusive access; consider calling MutableCollection.swapAt(_:_:)}}
|
||||
// expected-note@+1 {{conflicting access is here}}
|
||||
swap(&self.finalStored[0], &self.finalStored[1])
|
||||
swap(&self.overridableStored[0], &self.overridableStored[1])
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
// {"kind":"emit-sil","languageMode":6,"signature":"swift::regionanalysisimpl::BlockPartitionState::recomputeExitFromEntry(swift::regionanalysisimpl::PartitionOpTranslator&)","signatureAssert":"Assertion failed: (p.isTrackingElement(op.getOpArg1()) && \"Require PartitionOp's argument should already be tracked\"), function apply"}
|
||||
// RUN: not --crash %target-swift-frontend -emit-sil -swift-version 6 %s
|
||||
// RUN: not %target-swift-frontend -emit-sil -swift-version 6 %s
|
||||
func a<b>(d: b) {
|
||||
var e = 0
|
||||
let d: @convention(c) () -> Void = {
|
||||
Reference in New Issue
Block a user