Skip to content

Commit e97e07a

Browse files
committed
Fix SIL parsing of ownership qualifiers.
Errors were undiagnosed. Undiagnosed errors means that parsing fails without any line number information. This makes it impossible to hand-reduce OSSA test cases.
1 parent 9024f95 commit e97e07a

File tree

2 files changed

+81
-91
lines changed

2 files changed

+81
-91
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,7 @@ ERROR(referenced_value_no_accessor,none,
488488
"referenced declaration has no %select{getter|setter}0", (unsigned))
489489
ERROR(expected_sil_value_ownership_kind,none,
490490
"expected value ownership kind in SIL code", ())
491+
ERROR(unrecognized_sil_qualifier,none, "unrecognized SIL qualifier", ())
491492
ERROR(silfunc_and_silarg_have_incompatible_sil_value_ownership,none,
492493
"SILFunction and SILArgument have mismatching ValueOwnershipKinds. "
493494
"Function type specifies: '@%0'. SIL argument specifies: '@%1'.",

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 80 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,11 @@ namespace {
243243
return parseSILIdentifier(Result, L, Diagnostic(ID, Args...));
244244
}
245245

246+
template <typename T>
247+
bool
248+
parseSILQualifier(Optional<T> &result,
249+
llvm::function_ref<Optional<T>(StringRef)> parseName);
250+
246251
bool parseVerbatim(StringRef identifier);
247252

248253
template <typename T>
@@ -819,6 +824,38 @@ static bool parseSILOptional(bool &Result, SILParser &SP, StringRef Expected) {
819824
return false;
820825
}
821826

827+
// If the qualifier string is unrecognized, then diagnose and fail.
828+
//
829+
// If the qualifier is absent, then succeed and set the result to None.
830+
// The caller can decide how to proceed with an absent qualifier.
831+
//
832+
// Usage:
833+
// auto parseQualifierName = [](StringRef Str) {
834+
// return llvm::StringSwitch<Optional<SomeQualifier>>(Str)
835+
// .Case("one", SomeQualifier::One)
836+
// .Case("two", SomeQualifier::Two)
837+
// .Default(None);
838+
// };
839+
// if (parseSILQualifier<SomeQualifier>(Qualifier, parseQualifierName))
840+
// return true;
841+
template <typename T>
842+
bool SILParser::parseSILQualifier(
843+
Optional<T> &result, llvm::function_ref<Optional<T>(StringRef)> parseName) {
844+
auto loc = P.Tok.getLoc();
845+
StringRef Str;
846+
// If we do not parse '[' ... ']',
847+
if (!parseSILOptional(Str, *this)) {
848+
result = None;
849+
return false;
850+
}
851+
result = parseName(Str);
852+
if (!result) {
853+
P.diagnose(loc, Diagnostic(diag::unrecognized_sil_qualifier));
854+
return true;
855+
}
856+
return false;
857+
}
858+
822859
/// Remap RequirementReps to Requirements.
823860
void SILParser::convertRequirements(ArrayRef<RequirementRepr> From,
824861
SmallVectorImpl<Requirement> &To) {
@@ -2010,84 +2047,6 @@ bool SILParser::parseSILDebugLocation(SILLocation &L, SILBuilder &B,
20102047
return false;
20112048
}
20122049

2013-
static bool parseLoadOwnershipQualifier(LoadOwnershipQualifier &Result,
2014-
SILParser &P) {
2015-
StringRef Str;
2016-
// If we do not parse '[' ... ']', we have unqualified. Set value and return.
2017-
if (!parseSILOptional(Str, P)) {
2018-
Result = LoadOwnershipQualifier::Unqualified;
2019-
return false;
2020-
}
2021-
2022-
// Then try to parse one of our other qualifiers. We do not support parsing
2023-
// unqualified here so we use that as our fail value.
2024-
auto Tmp = llvm::StringSwitch<LoadOwnershipQualifier>(Str)
2025-
.Case("take", LoadOwnershipQualifier::Take)
2026-
.Case("copy", LoadOwnershipQualifier::Copy)
2027-
.Case("trivial", LoadOwnershipQualifier::Trivial)
2028-
.Default(LoadOwnershipQualifier::Unqualified);
2029-
2030-
// Thus return true (following the conventions in this file) if we fail.
2031-
if (Tmp == LoadOwnershipQualifier::Unqualified)
2032-
return true;
2033-
2034-
// Otherwise, assign Result and return false.
2035-
Result = Tmp;
2036-
return false;
2037-
}
2038-
2039-
static bool parseStoreOwnershipQualifier(StoreOwnershipQualifier &Result,
2040-
SILParser &P) {
2041-
StringRef Str;
2042-
// If we do not parse '[' ... ']', we have unqualified. Set value and return.
2043-
if (!parseSILOptional(Str, P)) {
2044-
Result = StoreOwnershipQualifier::Unqualified;
2045-
return false;
2046-
}
2047-
2048-
// Then try to parse one of our other qualifiers. We do not support parsing
2049-
// unqualified here so we use that as our fail value.
2050-
auto Tmp = llvm::StringSwitch<StoreOwnershipQualifier>(Str)
2051-
.Case("init", StoreOwnershipQualifier::Init)
2052-
.Case("assign", StoreOwnershipQualifier::Assign)
2053-
.Case("trivial", StoreOwnershipQualifier::Trivial)
2054-
.Default(StoreOwnershipQualifier::Unqualified);
2055-
2056-
// Thus return true (following the conventions in this file) if we fail.
2057-
if (Tmp == StoreOwnershipQualifier::Unqualified)
2058-
return true;
2059-
2060-
// Otherwise, assign Result and return false.
2061-
Result = Tmp;
2062-
return false;
2063-
}
2064-
2065-
static bool parseAssignOwnershipQualifier(AssignOwnershipQualifier &Result,
2066-
SILParser &P) {
2067-
StringRef Str;
2068-
// If we do not parse '[' ... ']', we have unknown. Set value and return.
2069-
if (!parseSILOptional(Str, P)) {
2070-
Result = AssignOwnershipQualifier::Unknown;
2071-
return false;
2072-
}
2073-
2074-
// Then try to parse one of our other initialization kinds. We do not support
2075-
// parsing unknown here so we use that as our fail value.
2076-
auto Tmp = llvm::StringSwitch<AssignOwnershipQualifier>(Str)
2077-
.Case("reassign", AssignOwnershipQualifier::Reassign)
2078-
.Case("reinit", AssignOwnershipQualifier::Reinit)
2079-
.Case("init", AssignOwnershipQualifier::Init)
2080-
.Default(AssignOwnershipQualifier::Unknown);
2081-
2082-
// Thus return true (following the conventions in this file) if we fail.
2083-
if (Tmp == AssignOwnershipQualifier::Unknown)
2084-
return true;
2085-
2086-
// Otherwise, assign Result and return false.
2087-
Result = Tmp;
2088-
return false;
2089-
}
2090-
20912050
static bool parseAssignByWrapperMode(AssignByWrapperInst::Mode &Result,
20922051
SILParser &P) {
20932052
StringRef Str;
@@ -3252,15 +3211,23 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
32523211
}
32533212

32543213
case SILInstructionKind::LoadInst: {
3255-
LoadOwnershipQualifier Qualifier;
3214+
Optional<LoadOwnershipQualifier> Qualifier;
32563215
SourceLoc AddrLoc;
3257-
3258-
if (parseLoadOwnershipQualifier(Qualifier, *this) ||
3259-
parseTypedValueRef(Val, AddrLoc, B) ||
3260-
parseSILDebugLocation(InstLoc, B))
3216+
auto parseLoadOwnership = [](StringRef Str) {
3217+
return llvm::StringSwitch<Optional<LoadOwnershipQualifier>>(Str)
3218+
.Case("take", LoadOwnershipQualifier::Take)
3219+
.Case("copy", LoadOwnershipQualifier::Copy)
3220+
.Case("trivial", LoadOwnershipQualifier::Trivial)
3221+
.Default(None);
3222+
};
3223+
if (parseSILQualifier<LoadOwnershipQualifier>(Qualifier, parseLoadOwnership)
3224+
|| parseTypedValueRef(Val, AddrLoc, B)
3225+
|| parseSILDebugLocation(InstLoc, B)) {
32613226
return true;
3262-
3263-
ResultVal = B.createLoad(InstLoc, Val, Qualifier);
3227+
}
3228+
if (!Qualifier)
3229+
Qualifier = LoadOwnershipQualifier::Unqualified;
3230+
ResultVal = B.createLoad(InstLoc, Val, Qualifier.getValue());
32643231
break;
32653232
}
32663233

@@ -3828,19 +3795,37 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
38283795
SourceLoc ToLoc, AddrLoc;
38293796
Identifier ToToken;
38303797
SILValue AddrVal;
3831-
StoreOwnershipQualifier StoreQualifier;
3832-
AssignOwnershipQualifier AssignQualifier;
3798+
Optional<StoreOwnershipQualifier> StoreQualifier;
3799+
Optional<AssignOwnershipQualifier> AssignQualifier;
38333800
bool IsStore = Opcode == SILInstructionKind::StoreInst;
38343801
bool IsAssign = Opcode == SILInstructionKind::AssignInst;
38353802
if (parseValueName(From) ||
38363803
parseSILIdentifier(ToToken, ToLoc, diag::expected_tok_in_sil_instr,
38373804
"to"))
38383805
return true;
38393806

3840-
if (IsStore && parseStoreOwnershipQualifier(StoreQualifier, *this))
3807+
auto parseStoreOwnership = [](StringRef Str) {
3808+
return llvm::StringSwitch<Optional<StoreOwnershipQualifier>>(Str)
3809+
.Case("init", StoreOwnershipQualifier::Init)
3810+
.Case("assign", StoreOwnershipQualifier::Assign)
3811+
.Case("trivial", StoreOwnershipQualifier::Trivial)
3812+
.Default(None);
3813+
};
3814+
if (IsStore
3815+
&& parseSILQualifier<StoreOwnershipQualifier>(StoreQualifier,
3816+
parseStoreOwnership))
38413817
return true;
38423818

3843-
if (IsAssign && parseAssignOwnershipQualifier(AssignQualifier, *this))
3819+
auto parseAssignOwnership = [](StringRef Str) {
3820+
return llvm::StringSwitch<Optional<AssignOwnershipQualifier>>(Str)
3821+
.Case("reassign", AssignOwnershipQualifier::Reassign)
3822+
.Case("reinit", AssignOwnershipQualifier::Reinit)
3823+
.Case("init", AssignOwnershipQualifier::Init)
3824+
.Default(None);
3825+
};
3826+
if (IsAssign
3827+
&& parseSILQualifier<AssignOwnershipQualifier>(AssignQualifier,
3828+
parseAssignOwnership))
38443829
return true;
38453830

38463831
if (parseTypedValueRef(AddrVal, AddrLoc, B) ||
@@ -3861,15 +3846,19 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
38613846
SILType ValType = AddrVal->getType().getObjectType();
38623847

38633848
if (IsStore) {
3849+
if (!StoreQualifier)
3850+
StoreQualifier = StoreOwnershipQualifier::Unqualified;
38643851
ResultVal =
38653852
B.createStore(InstLoc, getLocalValue(From, ValType, InstLoc, B),
3866-
AddrVal, StoreQualifier);
3853+
AddrVal, StoreQualifier.getValue());
38673854
} else {
38683855
assert(IsAssign);
3856+
if (!AssignQualifier)
3857+
AssignQualifier = AssignOwnershipQualifier::Unknown;
38693858

38703859
ResultVal =
38713860
B.createAssign(InstLoc, getLocalValue(From, ValType, InstLoc, B),
3872-
AddrVal, AssignQualifier);
3861+
AddrVal, AssignQualifier.getValue());
38733862
}
38743863

38753864
break;

0 commit comments

Comments
 (0)