Skip to content

[pull] swiftwasm-release/5.8 from release/5.8 #5257

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 4 commits into from
Feb 4, 2023
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
46 changes: 2 additions & 44 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1,44 +1,2 @@
# Lines starting with '#' are comments.
# Each line is a file pattern followed by one or more owners.
# Order is important. The last matching pattern has the most precedence.

# Owners of ASTGen
lib/ASTGen @zoecarver @CodaFi

# Dependency scanning
include/swift/DependencyScan @artemcm
lib/AST/ModuleLoader.cpp @artemcm
lib/DependencyScan @artemcm
lib/Frontend/ModuleInterfaceLoader.cpp @artemcm
lib/Serialization/SerializedModuleLoader.cpp @artemcm
test/ScanDependencies @artemcm

# Driver
include/swift/Driver @artemcm
lib/Driver @artemcm
test/Driver @artemcm

# Owners of the parser
include/swift/Parse @ahoppen @bnbarham @CodaFi @DougGregor @rintaro
lib/Parse @ahoppen @bnbarham @CodaFi @DougGregor @rintaro
test/Parse @ahoppen @bnbarham @CodaFi @DougGregor @rintaro

SwiftCompilerSources @eeckstein

# C++ Interop
include/swift/ClangImporter @zoecarver @hyp @egorzhdan
include/swift/PrintAsClang @zoecarver @hyp @egorzhdan
lib/ClangImporter @zoecarver @hyp @egorzhdan
lib/PrintAsClang @zoecarver @hyp @egorzhdan
stdlib/public/Cxx @zoecarver @hyp @egorzhdan
test/Interop @zoecarver @hyp @egorzhdan

# Threading implementation
include/swift/Threading @al45tair
lib/Threading @al45tair

# Windows support
cmake/**/*Windows* @compnerd
lib/Basic/Windows @compnerd
stdlib/public/Windows @compnerd
utils/*windows* @compnerd
# For the release branch @apple/swift5-branch-managers needs to approve the changes
* @apple/swift5-branch-managers
17 changes: 15 additions & 2 deletions SwiftCompilerSources/Sources/SIL/Location.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,24 @@

import SILBridging

public struct Location {
public struct Location: Equatable, CustomStringConvertible {
let bridged: swift.SILDebugLocation


public var description: String {
let stdString = SILLocation_debugDescription(bridged)
return String(_cxxString: stdString)
}

/// Keeps the debug scope but marks it as auto-generated.
public var autoGenerated: Location {
Location(bridged: SILLocation_getAutogeneratedLocation(bridged))
}

public static func ==(lhs: Location, rhs: Location) -> Bool {
SILLocation_equal(lhs.bridged, rhs.bridged)
}

public func hasSameSourceLocation(as other: Location) -> Bool {
SILLocation_hasSameSourceLocation(bridged, other.bridged)
}
}
3 changes: 3 additions & 0 deletions include/swift/SIL/SILBridging.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,8 +331,11 @@ llvm::StringRef SILType_getNominalFieldName(BridgedType type, SwiftInt index);
SwiftInt SILType_getCaseIdxOfEnumType(BridgedType type,
llvm::StringRef caseName);

std::string SILLocation_debugDescription(swift::SILDebugLocation loc);
swift::SILDebugLocation
SILLocation_getAutogeneratedLocation(swift::SILDebugLocation loc);
bool SILLocation_equal(swift::SILDebugLocation lhs, swift::SILDebugLocation rhs);
bool SILLocation_hasSameSourceLocation(swift::SILDebugLocation lhs, swift::SILDebugLocation rhs);

BridgedBasicBlock SILArgument_getParent(BridgedArgument argument);
BridgedArgumentConvention SILArgument_getConvention(BridgedArgument argument);
Expand Down
10 changes: 10 additions & 0 deletions include/swift/SIL/SILLocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,7 @@ class SILLocation {
/// Pretty-print the value.
void dump() const;
void print(raw_ostream &OS, const SourceManager &SM) const;
void print(raw_ostream &OS) const;

inline bool operator==(const SILLocation& R) const {
return kindAndFlags.packedKindAndFlags == R.kindAndFlags.packedKindAndFlags
Expand All @@ -435,6 +436,15 @@ class SILLocation {

inline bool operator!=(const SILLocation &R) const { return !(*this == R); }

bool hasSameSourceLocation(const SILLocation &rhs) {
if (*this == rhs)
return true;
if (isASTNode() && rhs.isASTNode()) {
return getSourceLoc(getPrimaryASTNode()) == rhs.getSourceLoc(rhs.getPrimaryASTNode());
}
return false;
}

friend llvm::hash_code hash_value(const SILLocation &);
};

Expand Down
24 changes: 18 additions & 6 deletions lib/SIL/IR/SILLocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,17 +151,17 @@ SILLocation::FilenameAndLocation *SILLocation::getCompilerGeneratedLoc() {
return &compilerGenerated;
}

static void dumpSourceLoc(SourceLoc loc) {
static void printSourceLoc(SourceLoc loc, raw_ostream &OS) {
if (!loc.isValid()) {
llvm::dbgs() << "<invalid loc>";
OS << "<invalid loc>";
return;
}
const char *srcPtr = (const char *)loc.getOpaquePointerValue();
unsigned len = strnlen(srcPtr, 20);
if (len < 20) {
llvm::dbgs() << '"' << StringRef(srcPtr, len) << '"';
OS << '"' << StringRef(srcPtr, len) << '"';
} else {
llvm::dbgs() << '"' << StringRef(srcPtr, 20) << "[...]\"";
OS << '"' << StringRef(srcPtr, 20) << "[...]\"";
}
}

Expand All @@ -182,7 +182,7 @@ void SILLocation::dump() const {
if (isFilenameAndLocation()) {
getFilenameAndLocation()->dump();
} else {
dumpSourceLoc(getSourceLoc());
printSourceLoc(getSourceLoc(), llvm::dbgs());
}

if (isAutoGenerated()) llvm::dbgs() << ":auto";
Expand All @@ -191,7 +191,7 @@ void SILLocation::dump() const {
if (isSILFile()) llvm::dbgs() << ":sil";
if (hasASTNodeForDebugging()) {
llvm::dbgs() << ":debug[";
dumpSourceLoc(getSourceLocForDebugging());
printSourceLoc(getSourceLocForDebugging(), llvm::dbgs());
llvm::dbgs() << "]\n";
}
}
Expand All @@ -206,6 +206,18 @@ void SILLocation::print(raw_ostream &OS, const SourceManager &SM) const {
}
}

void SILLocation::print(raw_ostream &OS) const {
if (isNull()) {
OS << "<no loc>";
} else if (isFilenameAndLocation()) {
getFilenameAndLocation()->print(OS);
} else if (DeclContext *dc = getAsDeclContext()){
getSourceLoc().print(OS, dc->getASTContext().SourceMgr);
} else {
printSourceLoc(getSourceLoc(), OS);
}
}

RegularLocation::RegularLocation(Stmt *S, Pattern *P, SILModule &Module) :
SILLocation(new (Module) ExtendedASTNodeLoc(S, P), RegularKind) {}

Expand Down
27 changes: 27 additions & 0 deletions lib/SIL/Utils/SILBridging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -607,12 +607,39 @@ SwiftInt SILType_getCaseIdxOfEnumType(BridgedType type,
// SILLocation
//===----------------------------------------------------------------------===//

std::string SILLocation_debugDescription(swift::SILDebugLocation dloc) {
std::string str;
llvm::raw_string_ostream os(str);
SILLocation loc = dloc.getLocation();
loc.print(os);
#ifndef NDEBUG
if (const SILDebugScope *scope = dloc.getScope()) {
if (DeclContext *dc = loc.getAsDeclContext()) {
os << ", scope=";
scope->print(dc->getASTContext().SourceMgr, os, /*indent*/ 2);
} else {
os << ", scope=?";
}
}
#endif
return str;
}

SILDebugLocation SILLocation_getAutogeneratedLocation(SILDebugLocation loc) {
SILDebugLocation autoGenLoc(RegularLocation::getAutoGeneratedLocation(),
loc.getScope());
return autoGenLoc;
}

bool SILLocation_equal(swift::SILDebugLocation lhs, swift::SILDebugLocation rhs) {
return lhs.getLocation() == rhs.getLocation() && lhs.getScope() == rhs.getScope();
}

bool SILLocation_hasSameSourceLocation(swift::SILDebugLocation lhs, swift::SILDebugLocation rhs) {
return lhs.getLocation().hasSameSourceLocation(rhs.getLocation()) &&
lhs.getScope() == rhs.getScope();
}

//===----------------------------------------------------------------------===//
// SILGlobalVariable
//===----------------------------------------------------------------------===//
Expand Down
60 changes: 40 additions & 20 deletions lib/SILOptimizer/Mandatory/DiagnoseUnreachable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,44 @@ static bool simplifyBlocksWithCallsToNoReturn(SILBasicBlock &BB,
// function, the entire block is dead.
NoReturnCall = getPrecedingCallToNoReturn(BB);

// Diagnose the unreachable code within the same block as the call to
// noreturn.
auto diagnoseUnreachableCode = [&](SILInstruction *noReturnCall,
SILInstruction *currInst) {
if (DiagnosedUnreachableCode)
return false;

// If current instruction belongs to the no-return call itself, skip it.
//
// It could happen when i.e. result has to be copied to be passed to
// some call.
if (currInst->getLoc().hasSameSourceLocation(noReturnCall->getLoc()))
return false;

if (!isUserCode(currInst))
return false;

// If we have an instruction that is an end_borrow, ignore it. This
// happens when passing a guaranteed argument through generic code paths
// to no return functions.
if (isa<EndBorrowInst>(currInst))
return false;

// If no-return instruction is not something we can point in code or
// it's an explicit cast, skip it.
if (!noReturnCall->getLoc().is<RegularLocation>() ||
noReturnCall->getLoc().isASTNode<ExplicitCastExpr>())
return false;

diagnose(BB.getModule().getASTContext(), currInst->getLoc().getSourceLoc(),
diag::unreachable_code);
diagnose(BB.getModule().getASTContext(),
noReturnCall->getLoc().getSourceLoc(),
diag::call_to_noreturn_note);

return true;
};

// Does this block contain a call to a noreturn function?
while (I != E) {
auto *CurrentInst = &*I;
Expand All @@ -758,26 +796,8 @@ static bool simplifyBlocksWithCallsToNoReturn(SILBasicBlock &BB,
// We will need to delete the instruction later on.
ToBeDeleted.push_back(CurrentInst);

// Diagnose the unreachable code within the same block as the call to
// noreturn.
if (isUserCode(CurrentInst) && !DiagnosedUnreachableCode) {
// If we have an instruction that is an end_borrow, ignore it. This
// happens when passing a guaranteed argument through generic code paths
// to no return functions.
if (!isa<EndBorrowInst>(CurrentInst)) {
if (NoReturnCall->getLoc().is<RegularLocation>()) {
if (!NoReturnCall->getLoc().isASTNode<ExplicitCastExpr>()) {
diagnose(BB.getModule().getASTContext(),
CurrentInst->getLoc().getSourceLoc(),
diag::unreachable_code);
diagnose(BB.getModule().getASTContext(),
NoReturnCall->getLoc().getSourceLoc(),
diag::call_to_noreturn_note);
DiagnosedUnreachableCode = true;
}
}
}
}
DiagnosedUnreachableCode |=
diagnoseUnreachableCode(NoReturnCall, CurrentInst);

// We are going to bluntly remove these instructions. Change uses in
// different basic blocks to undef. This is safe because all control flow
Expand Down
52 changes: 52 additions & 0 deletions test/SILOptimizer/diagnose_unreachable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -518,3 +518,55 @@ func keypathWithDynamicLookup() {
// when used in conjunction with a dynamicMemberLookup enum.
let _ = \DynamicLookupEnum.innerEnum // no warning
}

func test_no_warnings_with_fatalError_when_wrapped_in_buildExpression() {
enum Either<T,U> {
case first(T)
case second(U)
}

@resultBuilder
struct MyBuilder {
static func buildExpression<T>(_ e: T) -> T { e }
static func buildBlock() -> () { }

static func buildBlock<T1>(_ t1: T1) -> T1 {
return t1
}

static func buildBlock<T1, T2>(_ t1: T1, _ t2: T2) -> (T1, T2) {
return (t1, t2)
}

static func buildBlock<T1, T2, T3>(_ t1: T1, _ t2: T2, _ t3: T3) -> (T1, T2, T3) {
return (t1, t2, t3)
}

static func buildEither<T,U>(first value: T) -> Either<T, U> {
return .first(value)
}

static func buildEither<T,U>(second value: U) -> Either<T, U> {
return .second(value)
}
}

func test<T>(@MyBuilder _: (Int) -> T) {}

test {
if $0 < 0 {
fatalError() // ok, no warning even though fatalError() is wrapped
} else if $0 > 0 {
42
} else {
0
}
}

test {
switch $0 {
case 0: "0"
default: fatalError() // Ok, no warning even though fatalError() is wrapped
}
}
}