Skip to content

Commit 0df2987

Browse files
committed
[SE-0258] Fix source locations for implicitly-generated initializer calls.
Fixes rdar://problem/52969503, a crash due to missing source location information in implicitly-generated calls.
1 parent 10680e4 commit 0df2987

File tree

4 files changed

+33
-9
lines changed

4 files changed

+33
-9
lines changed

lib/AST/Decl.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5912,9 +5912,8 @@ Expr *swift::findOriginalPropertyWrapperInitialValue(VarDecl *var,
59125912
if (auto tuple = dyn_cast<TupleExpr>(call->getArg())) {
59135913
ASTContext &ctx = innermostNominal->getASTContext();
59145914
for (unsigned i : range(tuple->getNumElements())) {
5915-
if ((tuple->getElementName(i) == ctx.Id_wrappedValue ||
5916-
tuple->getElementName(i) == ctx.Id_initialValue) &&
5917-
tuple->getElementNameLoc(i).isInvalid()) {
5915+
if (tuple->getElementName(i) == ctx.Id_wrappedValue ||
5916+
tuple->getElementName(i) == ctx.Id_initialValue) {
59185917
initArg = tuple->getElement(i);
59195918
return { false, E };
59205919
}

lib/Sema/CSDiagnostics.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2912,14 +2912,22 @@ bool OutOfOrderArgumentFailure::diagnoseAsError() {
29122912
SourceLoc diagLoc = firstRange.Start;
29132913

29142914
auto addFixIts = [&](InFlightDiagnostic diag) {
2915+
// Don't add Fix-Its if one of the ranges is outside of the argument
2916+
// list, which can happen when we're splicing together an argument list
2917+
// from multiple sources.
2918+
auto &SM = getASTContext().SourceMgr;
2919+
auto argsRange = tuple->getSourceRange();
2920+
if (!SM.rangeContains(argsRange, firstRange) ||
2921+
!SM.rangeContains(argsRange, secondRange))
2922+
return;
2923+
29152924
diag.highlight(firstRange).highlight(secondRange);
29162925

29172926
// Move the misplaced argument by removing it from one location and
29182927
// inserting it in another location. To maintain argument comma
29192928
// separation, since the argument is always moving to an earlier index
29202929
// the preceding comma and whitespace is removed and a new trailing
29212930
// comma and space is inserted with the moved argument.
2922-
auto &SM = getASTContext().SourceMgr;
29232931
auto text = SM.extractText(
29242932
Lexer::getCharSourceRangeFromSourceRange(SM, firstRange));
29252933

lib/Sema/TypeCheckPropertyWrapper.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,8 @@ Expr *swift::buildPropertyWrapperInitialValueCall(
654654
wrapperAttrs[i]->getTypeLoc().getLoc(),
655655
wrapperType, ctx);
656656

657+
SourceLoc startLoc = wrapperAttrs[i]->getTypeLoc().getSourceRange().Start;
658+
657659
// If there were no arguments provided for the attribute at this level,
658660
// call `init(wrappedValue:)` directly.
659661
auto attr = wrapperAttrs[i];
@@ -664,8 +666,10 @@ Expr *swift::buildPropertyWrapperInitialValueCall(
664666
argName = init->getFullName().getArgumentNames()[0];
665667
}
666668

667-
initializer = CallExpr::createImplicit(
668-
ctx, typeExpr, {initializer}, {argName});
669+
initializer = CallExpr::create(
670+
ctx, typeExpr, startLoc, {initializer}, {argName},
671+
{initializer->getStartLoc()}, initializer->getEndLoc(),
672+
nullptr, /*implicit=*/true);
669673
continue;
670674
}
671675

@@ -675,7 +679,7 @@ Expr *swift::buildPropertyWrapperInitialValueCall(
675679
SmallVector<SourceLoc, 4> elementLocs;
676680
elements.push_back(initializer);
677681
elementNames.push_back(ctx.Id_wrappedValue);
678-
elementLocs.push_back(SourceLoc());
682+
elementLocs.push_back(initializer->getStartLoc());
679683

680684
if (auto tuple = dyn_cast<TupleExpr>(attr->getArg())) {
681685
for (unsigned i : range(tuple->getNumElements())) {
@@ -690,8 +694,9 @@ Expr *swift::buildPropertyWrapperInitialValueCall(
690694
elementLocs.push_back(SourceLoc());
691695
}
692696

693-
initializer = CallExpr::createImplicit(
694-
ctx, typeExpr, elements, elementNames);
697+
initializer = CallExpr::create(
698+
ctx, typeExpr, startLoc, elements, elementNames, elementLocs,
699+
attr->getArg()->getEndLoc(), nullptr, /*implicit=*/true);
695700
}
696701

697702
return initializer;

test/decl/var/property_wrappers.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,18 @@ struct TestAlias {
903903
@Alias var foo = 17
904904
}
905905

906+
// rdar://problem/52969503 - crash due to invalid source ranges in ill-formed
907+
// code.
908+
@propertyWrapper
909+
struct Wrap52969503<T> {
910+
var wrappedValue: T
911+
912+
init(blah: Int, wrappedValue: T) { }
913+
}
914+
915+
struct Test52969503 {
916+
@Wrap52969503(blah: 5) var foo: Int = 1 // expected-error{{argument 'blah' must precede argument 'wrappedValue'}}
917+
}
906918

907919

908920
//

0 commit comments

Comments
 (0)