Skip to content

Commit 0ace8fe

Browse files
authored
Merge pull request swiftlang#39054 from atrick/fix-ossa-parse
Fix SIL parsing of ownership qualifiers.
2 parents 1aafbed + e97e07a commit 0ace8fe

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

@@ -3838,19 +3805,37 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
38383805
SourceLoc ToLoc, AddrLoc;
38393806
Identifier ToToken;
38403807
SILValue AddrVal;
3841-
StoreOwnershipQualifier StoreQualifier;
3842-
AssignOwnershipQualifier AssignQualifier;
3808+
Optional<StoreOwnershipQualifier> StoreQualifier;
3809+
Optional<AssignOwnershipQualifier> AssignQualifier;
38433810
bool IsStore = Opcode == SILInstructionKind::StoreInst;
38443811
bool IsAssign = Opcode == SILInstructionKind::AssignInst;
38453812
if (parseValueName(From) ||
38463813
parseSILIdentifier(ToToken, ToLoc, diag::expected_tok_in_sil_instr,
38473814
"to"))
38483815
return true;
38493816

3850-
if (IsStore && parseStoreOwnershipQualifier(StoreQualifier, *this))
3817+
auto parseStoreOwnership = [](StringRef Str) {
3818+
return llvm::StringSwitch<Optional<StoreOwnershipQualifier>>(Str)
3819+
.Case("init", StoreOwnershipQualifier::Init)
3820+
.Case("assign", StoreOwnershipQualifier::Assign)
3821+
.Case("trivial", StoreOwnershipQualifier::Trivial)
3822+
.Default(None);
3823+
};
3824+
if (IsStore
3825+
&& parseSILQualifier<StoreOwnershipQualifier>(StoreQualifier,
3826+
parseStoreOwnership))
38513827
return true;
38523828

3853-
if (IsAssign && parseAssignOwnershipQualifier(AssignQualifier, *this))
3829+
auto parseAssignOwnership = [](StringRef Str) {
3830+
return llvm::StringSwitch<Optional<AssignOwnershipQualifier>>(Str)
3831+
.Case("reassign", AssignOwnershipQualifier::Reassign)
3832+
.Case("reinit", AssignOwnershipQualifier::Reinit)
3833+
.Case("init", AssignOwnershipQualifier::Init)
3834+
.Default(None);
3835+
};
3836+
if (IsAssign
3837+
&& parseSILQualifier<AssignOwnershipQualifier>(AssignQualifier,
3838+
parseAssignOwnership))
38543839
return true;
38553840

38563841
if (parseTypedValueRef(AddrVal, AddrLoc, B) ||
@@ -3871,15 +3856,19 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
38713856
SILType ValType = AddrVal->getType().getObjectType();
38723857

38733858
if (IsStore) {
3859+
if (!StoreQualifier)
3860+
StoreQualifier = StoreOwnershipQualifier::Unqualified;
38743861
ResultVal =
38753862
B.createStore(InstLoc, getLocalValue(From, ValType, InstLoc, B),
3876-
AddrVal, StoreQualifier);
3863+
AddrVal, StoreQualifier.getValue());
38773864
} else {
38783865
assert(IsAssign);
3866+
if (!AssignQualifier)
3867+
AssignQualifier = AssignOwnershipQualifier::Unknown;
38793868

38803869
ResultVal =
38813870
B.createAssign(InstLoc, getLocalValue(From, ValType, InstLoc, B),
3882-
AddrVal, AssignQualifier);
3871+
AddrVal, AssignQualifier.getValue());
38833872
}
38843873

38853874
break;

0 commit comments

Comments
 (0)