Skip to content

Commit 567e3d8

Browse files
authored
---
yaml --- r: 314871 b: refs/heads/master c: e066ab3 h: refs/heads/master i: 314869: 09ba317 314867: a049a9f 314863: de2ffdc
1 parent 5d3eadc commit 567e3d8

File tree

12 files changed

+161
-152
lines changed

12 files changed

+161
-152
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: c7978fa4778587643a8b4af0b2a527695d620097
2+
refs/heads/master: e066ab335a6282fb5256e18ce62d778317194642
33
refs/heads/master-next: 66a7e661ff8e88e2d4efab3e430197a7a941e352
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/include/swift/Serialization/ModuleFile.h

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -87,46 +87,11 @@ class ModuleFile
8787
/// A callback to be invoked every time a type was deserialized.
8888
std::function<void(Type)> DeserializedTypeCallback;
8989

90-
/// The number of entities that are currently being deserialized.
91-
unsigned NumCurrentDeserializingEntities = 0;
92-
9390
/// Is this module file actually a .sib file? .sib files are serialized SIL at
9491
/// arbitrary granularity and arbitrary stage; unlike serialized Swift
9592
/// modules, which are assumed to contain canonical SIL for an entire module.
9693
bool IsSIB = false;
9794

98-
/// RAII class to be used when deserializing an entity.
99-
class DeserializingEntityRAII {
100-
ModuleFile &MF;
101-
102-
public:
103-
DeserializingEntityRAII(ModuleFile &mf)
104-
: MF(mf.getModuleFileForDelayedActions()) {
105-
++MF.NumCurrentDeserializingEntities;
106-
}
107-
~DeserializingEntityRAII() {
108-
assert(MF.NumCurrentDeserializingEntities > 0 &&
109-
"Imbalanced currently-deserializing count?");
110-
if (MF.NumCurrentDeserializingEntities == 1) {
111-
MF.finishPendingActions();
112-
}
113-
114-
--MF.NumCurrentDeserializingEntities;
115-
}
116-
};
117-
friend class DeserializingEntityRAII;
118-
119-
/// Picks a specific ModuleFile instance to serve as the "delayer" for the
120-
/// entire module.
121-
///
122-
/// This is usually \c this, but when there are partial swiftmodules all
123-
/// loaded for the same module it may be different.
124-
ModuleFile &getModuleFileForDelayedActions();
125-
126-
/// Finish any pending actions that were waiting for the topmost entity to
127-
/// be deserialized.
128-
void finishPendingActions();
129-
13095
public:
13196
/// Represents another module that has been imported as a dependency.
13297
class Dependency {

trunk/lib/AST/ASTVerifier.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2362,14 +2362,6 @@ class Verifier : public ASTWalker {
23622362
}
23632363
}
23642364

2365-
if (VD->isFinal() != VD->getAttrs().hasAttribute<FinalAttr>()) {
2366-
Out << "decl should be final iff it has FinalAttr, but isFinal() = "
2367-
<< VD->isFinal() << " and hasAttribute<FinalAttr>() = "
2368-
<< VD->getAttrs().hasAttribute<FinalAttr>() << "\n";
2369-
VD->dump(Out);
2370-
abort();
2371-
}
2372-
23732365
verifyCheckedBase(VD);
23742366
}
23752367

trunk/lib/SIL/LinearLifetimeChecker.cpp

Lines changed: 84 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,14 @@ namespace {
4242
using BrPropUserAndBlockPair = std::pair<BranchPropagatedUser, SILBasicBlock *>;
4343

4444
struct State {
45-
/// The value that we are checking.
46-
SILValue value;
45+
/// If we are checking for a specific value, this is that value. This is only
46+
/// used for diagnostic purposes. The algorithm if this is set works on the
47+
/// parent block of the value.
48+
Optional<SILValue> value;
49+
50+
/// The block where the live range begins. If the field value is not None,
51+
/// then this is value->getParentBlock();
52+
SILBasicBlock *beginBlock;
4753

4854
/// The result error object that use to signal either that no errors were
4955
/// found or if errors are found the specific type of error that was found.
@@ -75,8 +81,15 @@ struct State {
7581
State(SILValue value, SmallPtrSetImpl<SILBasicBlock *> &visitedBlocks,
7682
ErrorBehaviorKind errorBehavior,
7783
SmallVectorImpl<SILBasicBlock *> *leakingBlocks)
78-
: value(value), error(errorBehavior), visitedBlocks(visitedBlocks),
79-
leakingBlocks(leakingBlocks) {}
84+
: value(value), beginBlock(value->getParentBlock()), error(errorBehavior),
85+
visitedBlocks(visitedBlocks), leakingBlocks(leakingBlocks) {}
86+
87+
State(SILBasicBlock *beginBlock,
88+
SmallPtrSetImpl<SILBasicBlock *> &visitedBlocks,
89+
ErrorBehaviorKind errorBehavior,
90+
SmallVectorImpl<SILBasicBlock *> *leakingBlocks)
91+
: value(), beginBlock(beginBlock), error(errorBehavior),
92+
visitedBlocks(visitedBlocks), leakingBlocks(leakingBlocks) {}
8093

8194
void initializeAllNonConsumingUses(
8295
ArrayRef<BranchPropagatedUser> nonConsumingUsers);
@@ -183,7 +196,7 @@ void State::initializeAllConsumingUses(
183196
// If this user is in the same block as the value, do not visit
184197
// predecessors. We must be extra tolerant here since we allow for
185198
// unreachable code.
186-
if (userBlock == value->getParentBlock())
199+
if (userBlock == beginBlock)
187200
continue;
188201

189202
// Then for each predecessor of this block...
@@ -203,10 +216,15 @@ void State::initializeConsumingUse(BranchPropagatedUser consumingUser,
203216
return;
204217

205218
error.handleOverConsume([&] {
206-
llvm::errs() << "Function: '" << value->getFunction()->getName() << "'\n"
207-
<< "Found over consume?!\n"
208-
<< "Value: " << *value << "User: " << *consumingUser
209-
<< "Block: bb" << userBlock->getDebugID() << "\n\n";
219+
llvm::errs() << "Function: '" << beginBlock->getParent()->getName() << "'\n"
220+
<< "Found over consume?!\n";
221+
if (auto v = value) {
222+
llvm::errs() << "Value: " << *value;
223+
} else {
224+
llvm::errs() << "Value: N/A\n";
225+
}
226+
llvm::errs() << "User: " << *consumingUser << "Block: bb"
227+
<< userBlock->getDebugID() << "\n\n";
210228
});
211229
}
212230

@@ -228,10 +246,16 @@ void State::checkForSameBlockUseAfterFree(BranchPropagatedUser consumingUser,
228246
// the cond branch user is in a previous block. So just bail early.
229247
if (consumingUser.isCondBranchUser()) {
230248
error.handleUseAfterFree([&]() {
231-
llvm::errs() << "Function: '" << value->getFunction()->getName() << "'\n"
249+
llvm::errs() << "Function: '" << beginBlock->getParent()->getName()
250+
<< "'\n"
232251
<< "Found use after free?!\n"
233-
<< "Value: " << *value
234-
<< "Consuming User: " << *consumingUser
252+
<< "Value: ";
253+
if (auto v = value) {
254+
llvm::errs() << *v;
255+
} else {
256+
llvm::errs() << "N/A. \n";
257+
}
258+
llvm::errs() << "Consuming User: " << *consumingUser
235259
<< "Non Consuming User: " << *iter->second << "Block: bb"
236260
<< userBlock->getDebugID() << "\n\n";
237261
});
@@ -255,10 +279,16 @@ void State::checkForSameBlockUseAfterFree(BranchPropagatedUser consumingUser,
255279
return nonConsumingUser == &i;
256280
}) != userBlock->end()) {
257281
error.handleUseAfterFree([&] {
258-
llvm::errs() << "Function: '" << value->getFunction()->getName() << "'\n"
282+
llvm::errs() << "Function: '" << beginBlock->getParent()->getName()
283+
<< "'\n"
259284
<< "Found use after free?!\n"
260-
<< "Value: " << *value
261-
<< "Consuming User: " << *consumingUser
285+
<< "Value: ";
286+
if (auto v = value) {
287+
llvm::errs() << *v;
288+
} else {
289+
llvm::errs() << "N/A. \n";
290+
}
291+
llvm::errs() << "Consuming User: " << *consumingUser
262292
<< "Non Consuming User: " << *iter->second << "Block: bb"
263293
<< userBlock->getDebugID() << "\n\n";
264294
});
@@ -287,10 +317,17 @@ void State::checkPredsForDoubleConsume(BranchPropagatedUser consumingUser,
287317
}
288318

289319
error.handleOverConsume([&] {
290-
llvm::errs() << "Function: '" << value->getFunction()->getName() << "'\n"
320+
llvm::errs() << "Function: '" << beginBlock->getParent()->getName() << "'\n"
291321
<< "Found over consume?!\n"
292-
<< "Value: " << *value << "User: " << *consumingUser
293-
<< "Block: bb" << userBlock->getDebugID() << "\n\n";
322+
<< "Value: ";
323+
if (auto v = value) {
324+
llvm::errs() << *v;
325+
} else {
326+
llvm::errs() << "N/A. \n";
327+
}
328+
329+
llvm::errs() << "User: " << *consumingUser << "Block: bb"
330+
<< userBlock->getDebugID() << "\n\n";
294331
});
295332
}
296333

@@ -310,10 +347,16 @@ void State::checkPredsForDoubleConsume(SILBasicBlock *userBlock) {
310347
}
311348

312349
error.handleOverConsume([&] {
313-
llvm::errs() << "Function: '" << value->getFunction()->getName() << "'\n"
350+
llvm::errs() << "Function: '" << beginBlock->getParent()->getName() << "'\n"
314351
<< "Found over consume?!\n"
315-
<< "Value: " << *value << "Block: bb"
316-
<< userBlock->getDebugID() << "\n\n";
352+
<< "Value: ";
353+
if (auto v = value) {
354+
llvm::errs() << *v;
355+
} else {
356+
llvm::errs() << "N/A. \n";
357+
}
358+
359+
llvm::errs() << "Block: bb" << userBlock->getDebugID() << "\n\n";
317360
});
318361
}
319362

@@ -370,7 +413,7 @@ void State::performDataflow(DeadEndBlocks &deBlocks) {
370413
// further to do since we do not want to visit the predecessors of our
371414
// dominating block. On the other hand, we do want to add its successors to
372415
// the successorBlocksThatMustBeVisited set.
373-
if (block == value->getParentBlock())
416+
if (block == beginBlock)
374417
continue;
375418

376419
// Then for each predecessor of this block:
@@ -405,11 +448,16 @@ void State::checkDataflowEndState(DeadEndBlocks &deBlocks) {
405448

406449
// If we are supposed to error on leaks, do so now.
407450
error.handleLeak([&] {
408-
llvm::errs() << "Function: '" << value->getFunction()->getName() << "'\n"
451+
llvm::errs() << "Function: '" << beginBlock->getParent()->getName()
452+
<< "'\n"
409453
<< "Error! Found a leak due to a consuming post-dominance "
410-
"failure!\n"
411-
<< " Value: " << *value
412-
<< " Post Dominating Failure Blocks:\n";
454+
"failure!\n";
455+
if (auto v = value) {
456+
llvm::errs() << "Value: " << *value;
457+
} else {
458+
llvm::errs() << "Value: N/A\n";
459+
}
460+
llvm::errs() << " Post Dominating Failure Blocks:\n";
413461
for (auto *succBlock : successorBlocksThatMustBeVisited) {
414462
llvm::errs() << " bb" << succBlock->getDebugID();
415463
}
@@ -434,10 +482,18 @@ void State::checkDataflowEndState(DeadEndBlocks &deBlocks) {
434482
}
435483

436484
error.handleUseAfterFree([&] {
437-
llvm::errs() << "Function: '" << value->getFunction()->getName() << "'\n"
485+
llvm::errs() << "Function: '" << beginBlock->getParent()->getName()
486+
<< "'\n"
438487
<< "Found use after free due to unvisited non lifetime "
439488
"ending uses?!\n"
440-
<< "Value: " << *value << " Remaining Users:\n";
489+
<< "Value: ";
490+
if (auto v = value) {
491+
llvm::errs() << *v;
492+
} else {
493+
llvm::errs() << "N/A. \n";
494+
}
495+
496+
llvm::errs() << " Remaining Users:\n";
441497
for (auto &pair : blocksWithNonConsumingUses) {
442498
llvm::errs() << "User:" << *pair.second << "Block: bb"
443499
<< pair.first->getDebugID() << "\n";

trunk/lib/Sema/CSDiag.cpp

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1683,43 +1683,6 @@ bool FailureDiagnosis::diagnoseContextualConversionError(
16831683
if (isUnresolvedOrTypeVarType(exprType) || exprType->isEqual(contextualType))
16841684
return false;
16851685

1686-
// If this is conversion failure due to a return statement with an argument
1687-
// that cannot be coerced to the result type of the function, emit a
1688-
// specific error.
1689-
if (CTP == CTP_ThrowStmt) {
1690-
// If we tried to throw the error code of an error type, suggest object
1691-
// construction.
1692-
auto &TC = CS.getTypeChecker();
1693-
if (auto errorCodeProtocol =
1694-
TC.Context.getProtocol(KnownProtocolKind::ErrorCodeProtocol)) {
1695-
if (auto conformance = TypeChecker::conformsToProtocol(
1696-
CS.getType(expr), errorCodeProtocol, CS.DC,
1697-
ConformanceCheckFlags::InExpression)) {
1698-
Type errorCodeType = CS.getType(expr);
1699-
Type errorType =
1700-
conformance
1701-
->getTypeWitnessByName(errorCodeType, TC.Context.Id_ErrorType)
1702-
->getCanonicalType();
1703-
if (errorType) {
1704-
auto diag = diagnose(expr->getLoc(), diag::cannot_throw_error_code,
1705-
errorCodeType, errorType);
1706-
if (auto unresolvedDot = dyn_cast<UnresolvedDotExpr>(expr)) {
1707-
diag.fixItInsert(unresolvedDot->getDotLoc(), "(");
1708-
diag.fixItInsertAfter(unresolvedDot->getEndLoc(), ")");
1709-
}
1710-
return true;
1711-
}
1712-
}
1713-
}
1714-
1715-
// The conversion destination of throw is always ErrorType (at the moment)
1716-
// if this ever expands, this should be a specific form like () is for
1717-
// return.
1718-
diagnose(expr->getLoc(), diag::cannot_convert_thrown_type, exprType)
1719-
.highlight(expr->getSourceRange());
1720-
return true;
1721-
}
1722-
17231686
if (CTP == CTP_YieldByReference) {
17241687
if (auto contextualLV = contextualType->getAs<LValueType>())
17251688
contextualType = contextualLV->getObjectType();

trunk/lib/Sema/CSDiagnostics.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1882,6 +1882,9 @@ bool ContextualFailure::diagnoseAsError() {
18821882
if (diagnoseConversionToBool())
18831883
return true;
18841884

1885+
if (diagnoseThrowsTypeMismatch())
1886+
return true;
1887+
18851888
auto contextualType = getToType();
18861889
if (auto msg = getDiagnosticFor(CTP, contextualType->isExistentialType())) {
18871890
diagnostic = *msg;
@@ -2191,6 +2194,50 @@ bool ContextualFailure::diagnoseConversionToDictionary() const {
21912194
return true;
21922195
}
21932196

2197+
bool ContextualFailure::diagnoseThrowsTypeMismatch() const {
2198+
// If this is conversion failure due to a return statement with an argument
2199+
// that cannot be coerced to the result type of the function, emit a
2200+
// specific error.
2201+
if (CTP != CTP_ThrowStmt)
2202+
return false;
2203+
2204+
auto *anchor = getAnchor();
2205+
2206+
// If we tried to throw the error code of an error type, suggest object
2207+
// construction.
2208+
auto &TC = getTypeChecker();
2209+
if (auto errorCodeProtocol =
2210+
TC.Context.getProtocol(KnownProtocolKind::ErrorCodeProtocol)) {
2211+
Type errorCodeType = getFromType();
2212+
if (auto conformance = TypeChecker::conformsToProtocol(
2213+
errorCodeType, errorCodeProtocol, getDC(),
2214+
ConformanceCheckFlags::InExpression)) {
2215+
Type errorType = conformance
2216+
->getTypeWitnessByName(errorCodeType,
2217+
getASTContext().Id_ErrorType)
2218+
->getCanonicalType();
2219+
if (errorType) {
2220+
auto diagnostic =
2221+
emitDiagnostic(anchor->getLoc(), diag::cannot_throw_error_code,
2222+
errorCodeType, errorType);
2223+
if (auto *UDE = dyn_cast<UnresolvedDotExpr>(anchor)) {
2224+
diagnostic.fixItInsert(UDE->getDotLoc(), "(");
2225+
diagnostic.fixItInsertAfter(UDE->getEndLoc(), ")");
2226+
}
2227+
return true;
2228+
}
2229+
}
2230+
}
2231+
2232+
// The conversion destination of throw is always ErrorType (at the moment)
2233+
// if this ever expands, this should be a specific form like () is for
2234+
// return.
2235+
emitDiagnostic(anchor->getLoc(), diag::cannot_convert_thrown_type,
2236+
getFromType())
2237+
.highlight(anchor->getSourceRange());
2238+
return true;
2239+
}
2240+
21942241
bool ContextualFailure::tryRawRepresentableFixIts(
21952242
InFlightDiagnostic &diagnostic,
21962243
KnownProtocolKind rawRepresentableProtocol) const {

trunk/lib/Sema/CSDiagnostics.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,10 @@ class ContextualFailure : public FailureDiagnostic {
629629
/// or convert an array literal to a dictionary e.g. `let _: [String: Int] = ["A", 0]`
630630
bool diagnoseConversionToDictionary() const;
631631

632+
/// Produce a specialized diagnostic if this is an attempt to throw
633+
/// something with doesn't conform to `Error`.
634+
bool diagnoseThrowsTypeMismatch() const;
635+
632636
/// Attempt to attach any relevant fix-its to already produced diagnostic.
633637
void tryFixIts(InFlightDiagnostic &diagnostic) const;
634638

0 commit comments

Comments
 (0)