Skip to content

More fuzzer fixes #82275

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 11 commits into from
Jun 17, 2025
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
7 changes: 2 additions & 5 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -1436,10 +1436,10 @@ ERROR(did_not_call_function_value,none,
())
ERROR(did_not_call_function,none,
"function %0 was used as a property; add () to call it",
(Identifier))
(DeclBaseName))
ERROR(did_not_call_method,none,
"method %0 was used as a property; add () to call it",
(Identifier))
(DeclBaseName))

ERROR(init_not_instance_member_use_assignment,none,
"'init' is a member of the type; use assignment "
Expand Down Expand Up @@ -3781,9 +3781,6 @@ ERROR(enum_non_integer_convertible_raw_type_no_value,none,
"expressible by integer or string literal", ())
ERROR(enum_raw_value_not_unique,none,
"raw value for enum case is not unique", ())
ERROR(enum_raw_value_magic_literal,none,
"use of '%0' literal as raw value for enum case is not supported",
(StringRef))
NOTE(enum_raw_value_used_here,none,
"raw value previously used here", ())
NOTE(enum_raw_value_incrementing_from_here,none,
Expand Down
2 changes: 2 additions & 0 deletions lib/AST/ASTScope.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,8 @@ SourceRange NominalTypeScope::getBraces() const { return decl->getBraces(); }

NullablePtr<NominalTypeDecl>
ExtensionScope::getCorrespondingNominalTypeDecl() const {
if (!decl->hasBeenBound())
return nullptr;
return decl->getExtendedNominal();
}

Expand Down
7 changes: 5 additions & 2 deletions lib/AST/ProtocolConformance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -990,9 +990,12 @@ static bool isVanishingTupleConformance(

auto replacementTypes = substitutions.getReplacementTypes();
assert(replacementTypes.size() == 1);
auto packType = replacementTypes[0]->castTo<PackType>();

return (packType->getNumElements() == 1 &&
// This might not be an actual pack type with an invalid tuple conformance.
auto packType = replacementTypes[0]->getAs<PackType>();

return (packType &&
packType->getNumElements() == 1 &&
!packType->getElementTypes()[0]->is<PackExpansionType>());
}

Expand Down
1 change: 1 addition & 0 deletions lib/AST/RequirementMachine/RequirementLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,7 @@ static void desugarSameShapeRequirement(
!req.getSecondType()->isParameterPack()) {
errors.push_back(RequirementError::forInvalidShapeRequirement(
req, loc));
return;
}

result.emplace_back(RequirementKind::SameShape,
Expand Down
24 changes: 18 additions & 6 deletions lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6337,8 +6337,8 @@ ParserStatus Parser::parseDecl(bool IsAtStartOfLineOrPreviousHadSemi,
DescriptiveKind = DescriptiveDeclKind::StaticProperty;
break;
case StaticSpellingKind::KeywordClass:
llvm_unreachable("kw_class is only parsed as a modifier if it's "
"followed by a keyword");
DescriptiveKind = DescriptiveDeclKind::ClassProperty;
break;
}

diagnose(Tok.getLoc(), diag::expected_keyword_in_decl, "var",
Expand Down Expand Up @@ -6366,8 +6366,7 @@ ParserStatus Parser::parseDecl(bool IsAtStartOfLineOrPreviousHadSemi,
DescriptiveKind = DescriptiveDeclKind::StaticMethod;
break;
case StaticSpellingKind::KeywordClass:
llvm_unreachable("kw_class is only parsed as a modifier if it's "
"followed by a keyword");
DescriptiveKind = DescriptiveDeclKind::ClassMethod;
}
}

Expand Down Expand Up @@ -9229,6 +9228,20 @@ ParserResult<EnumDecl> Parser::parseDeclEnum(ParseDeclOptions Flags,
return DCC.fixupParserResult(Status, ED);
}

static bool isValidEnumRawValueLiteral(LiteralExpr *expr) {
if (expr == nullptr)
return false;

if (!isa<IntegerLiteralExpr>(expr) &&
!isa<FloatLiteralExpr>(expr) &&
!isa<StringLiteralExpr>(expr) &&
!isa<BooleanLiteralExpr>(expr) &&
!isa<NilLiteralExpr>(expr))
return false;

return true;
}

/// Parse a 'case' of an enum.
///
/// \verbatim
Expand Down Expand Up @@ -9346,8 +9359,7 @@ Parser::parseDeclEnumCase(ParseDeclOptions Flags,
}
// The raw value must be syntactically a simple literal.
LiteralRawValueExpr = dyn_cast<LiteralExpr>(RawValueExpr.getPtrOrNull());
if (!LiteralRawValueExpr
|| isa<InterpolatedStringLiteralExpr>(LiteralRawValueExpr)) {
if (!isValidEnumRawValueLiteral(LiteralRawValueExpr)) {
diagnose(RawValueExpr.getPtrOrNull()->getLoc(),
diag::nonliteral_enum_case_raw_value);
LiteralRawValueExpr = nullptr;
Expand Down
6 changes: 3 additions & 3 deletions lib/Sema/CSDiagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3940,22 +3940,22 @@ bool MissingCallFailure::diagnoseAsError() {

if (auto *DRE = getAsExpr<DeclRefExpr>(anchor)) {
emitDiagnostic(diag::did_not_call_function,
DRE->getDecl()->getBaseIdentifier())
DRE->getDecl()->getBaseName())
.fixItInsertAfter(insertLoc, "()");
return true;
}

if (auto *UDE = getAsExpr<UnresolvedDotExpr>(anchor)) {
emitDiagnostic(diag::did_not_call_method,
UDE->getName().getBaseIdentifier())
UDE->getName().getBaseName())
.fixItInsertAfter(insertLoc, "()");
return true;
}

if (auto *DSCE = getAsExpr<DotSyntaxCallExpr>(anchor)) {
if (auto *DRE = dyn_cast<DeclRefExpr>(DSCE->getFn())) {
emitDiagnostic(diag::did_not_call_method,
DRE->getDecl()->getBaseIdentifier())
DRE->getDecl()->getBaseName())
.fixItInsertAfter(insertLoc, "()");
return true;
}
Expand Down
3 changes: 3 additions & 0 deletions lib/Sema/DerivedConformance/DerivedConformance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,9 @@ void DerivedConformance::diagnoseIfSynthesisUnsupportedForDecl(
shouldDiagnose = !isa<EnumDecl>(nominal);
}

if (isa<BuiltinTupleDecl>(nominal))
shouldDiagnose = false;

if (shouldDiagnose) {
auto &ctx = nominal->getASTContext();
ctx.Diags.diagnose(nominal->getLoc(),
Expand Down
4 changes: 2 additions & 2 deletions lib/Sema/MiscDiagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6268,9 +6268,9 @@ diagnoseDictionaryLiteralDuplicateKeyEntries(const Expr *E,
note.fixItRemove(duplicated.first->getSourceRange());
if (duplicatedEltIdx < commanLocs.size()) {
note.fixItRemove(commanLocs[duplicatedEltIdx]);
} else {
} else if (!commanLocs.empty()) {
// For the last element remove the previous comma.
note.fixItRemove(commanLocs[duplicatedEltIdx - 1]);
note.fixItRemove(commanLocs[commanLocs.size() - 1]);
}
};

Expand Down
9 changes: 0 additions & 9 deletions lib/Sema/TypeCheckDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1304,15 +1304,6 @@ EnumRawValuesRequest::evaluate(Evaluator &eval, EnumDecl *ED,
SourceLoc diagLoc = uncheckedRawValueOf(elt)->isImplicit()
? elt->getLoc()
: uncheckedRawValueOf(elt)->getLoc();
if (auto magicLiteralExpr =
dyn_cast<MagicIdentifierLiteralExpr>(prevValue)) {
auto kindString =
magicLiteralExpr->getKindString(magicLiteralExpr->getKind());
Diags.diagnose(diagLoc, diag::enum_raw_value_magic_literal, kindString);
elt->setInvalid();
continue;
}

// Check that the raw value is unique.
RawValueKey key{prevValue};
RawValueSource source{elt, lastExplicitValueElt};
Expand Down
3 changes: 3 additions & 0 deletions lib/Sema/TypeCheckDeclOverride.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ bool swift::isOverrideBasedOnType(const ValueDecl *decl, Type declTy,
return false;
}

if (declTy->is<ErrorType>())
return false;

auto fnType1 = declTy->castTo<AnyFunctionType>();
auto fnType2 = parentDeclTy->castTo<AnyFunctionType>();
return AnyFunctionType::equalParams(fnType1->getParams(),
Expand Down
23 changes: 16 additions & 7 deletions lib/Sema/TypeCheckProtocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3888,10 +3888,19 @@ filterProtocolRequirements(
return Filtered;
}

const auto getProtocolSubstitutionMap = [&](ValueDecl *Req) {
auto *const PD = cast<ProtocolDecl>(Req->getDeclContext());
auto Conformance = lookupConformance(Adoptee, PD);
return SubstitutionMap::getProtocolSubstitutions(Conformance);
const auto getProtocolSubstitutionMap = [&](ValueDecl *req) {
ASSERT(isa<ProtocolDecl>(req->getDeclContext()));
auto genericSig = req->getInnermostDeclContext()
->getGenericSignatureOfContext();
SmallVector<Type, 2> args;
for (auto paramTy : genericSig.getGenericParams()) {
if (args.empty())
args.push_back(Adoptee);
else
args.push_back(paramTy);
}
return SubstitutionMap::get(genericSig, args,
LookUpConformanceInModule());
};

llvm::SmallDenseMap<DeclName, llvm::SmallVector<ValueDecl *, 2>, 4>
Expand All @@ -3907,11 +3916,11 @@ filterProtocolRequirements(
auto OverloadTy = Req->getOverloadSignatureType();
if (OverloadTy) {
auto Subs = getProtocolSubstitutionMap(Req);
// FIXME: This is wrong if the overload has its own generic parameters
if (auto GenericFnTy = dyn_cast<GenericFunctionType>(OverloadTy))
if (auto GenericFnTy = dyn_cast<GenericFunctionType>(OverloadTy)) {
OverloadTy = GenericFnTy.substGenericArgs(Subs);
else
} else {
OverloadTy = OverloadTy.subst(Subs)->getCanonicalType();
}
}
if (llvm::any_of(DeclsByName[Req->getName()], [&](ValueDecl *OtherReq) {
auto OtherOverloadTy = OtherReq->getOverloadSignatureType();
Expand Down
7 changes: 4 additions & 3 deletions lib/Sema/TypeCheckStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2996,9 +2996,10 @@ LazyStoragePropertyRequest::evaluate(Evaluator &evaluator,
addMemberToContextIfNeeded(PBD, VD->getDeclContext(), Storage);

// Make sure the original init is marked as subsumed.
auto *originalPBD = VD->getParentPatternBinding();
auto originalIndex = originalPBD->getPatternEntryIndexForVarDecl(VD);
originalPBD->setInitializerSubsumed(originalIndex);
if (auto *originalPBD = VD->getParentPatternBinding()) {
auto originalIndex = originalPBD->getPatternEntryIndexForVarDecl(VD);
originalPBD->setInitializerSubsumed(originalIndex);
}

return Storage;
}
Expand Down
5 changes: 5 additions & 0 deletions test/Generics/tuple-conformances-synthesize-crash.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// RUN: not %target-swift-frontend -typecheck %s

// Just don't crash.
extension () : Comparable {}

7 changes: 7 additions & 0 deletions test/decl/enum/invalid_raw_value.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// RUN: %target-typecheck-verify-swift

_ = a.init
_ = b.init

enum a : Int { case x = #/ /# } // expected-error {{raw value for enum case must be a literal}}
enum b : String { case x = #file } // expected-error {{raw value for enum case must be a literal}}
13 changes: 13 additions & 0 deletions test/decl/protocol/conforms/fixit_stub_generic.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// RUN: %target-typecheck-verify-swift

protocol P1 {
associatedtype A
}

protocol P2 {
func f<T>(_: T, _: T) // expected-note {{protocol requires function 'f' with type '<T> (T, T) -> ()'}}
func f<T: P1>(_: T, _: T.A) // expected-note {{protocol requires function 'f' with type '<T> (T, T.A) -> ()'}}
}

struct S: P2 {} // expected-error {{type 'S' does not conform to protocol 'P2'}}
// expected-note@-1 {{add stubs for conformance}}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// {"signature":"swift::Parser::parseNewDeclAttribute(swift::DeclAttributes&, swift::SourceLoc, swift::DeclAttrKind, bool)::$_4::operator()() const"}
// RUN: not --crash %target-swift-frontend -typecheck %s
// RUN: not %target-swift-frontend -typecheck %s
class a {
class override b
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// {"signature":"swift::LazyStoragePropertyRequest::evaluate(swift::Evaluator&, swift::VarDecl*) const"}
// RUN: not --crash %target-swift-frontend -typecheck %s
// RUN: not %target-swift-frontend -typecheck %s
class a {
lazy(b, c) {
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// {"signature":"swift::Parser::parseDecl(bool, bool, llvm::function_ref<void (swift::Decl*)>, bool)"}
// RUN: not --crash %target-swift-frontend -typecheck %s
// RUN: not %target-swift-frontend -typecheck %s
class a { class override ( override
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// {"signature":"swift::GenericContext::getGenericParams() const"}
// RUN: not --crash %target-swift-frontend -typecheck %s
// RUN: not %target-swift-frontend -typecheck %s
typealias a = () extension a : Comparable
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// {"signature":"swift::rewriting::RequirementMachine::getReducedShape(swift::Type, llvm::ArrayRef<swift::GenericTypeParamType*>) const"}
// RUN: not --crash %target-swift-frontend -typecheck %s
// RUN: not %target-swift-frontend -typecheck %s
protocol a{ b < c > (c, _ : c}
protocol d : a{
b<c : e>(c, c.c) protocol e {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// {"signature":"deriveBodyRawRepresentable_init(swift::AbstractFunctionDecl*, void*)"}
// RUN: not --crash %target-swift-frontend -typecheck %s
// RUN: not %target-swift-frontend -typecheck %s
a enum a : Int { case = #/
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// {"signature":"swift::isOverrideBasedOnType(swift::ValueDecl const*, swift::Type, swift::ValueDecl const*)"}
// RUN: not --crash %target-swift-frontend -typecheck %s
// RUN: not %target-swift-frontend -typecheck %s
struct a < b {
protocol c { associatedtype d init(e : d
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// {"signature":"diagnoseDictionaryLiteralDuplicateKeyEntries(swift::Expr const*, swift::DeclContext const*)::DiagnoseWalker::walkToExprPre(swift::Expr*)"}
// RUN: not --crash %target-swift-frontend -typecheck %s
// RUN: not %target-swift-frontend -typecheck %s
[ 1.01: "" 1.01: ""
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// {"signature":"(anonymous namespace)::ABIDependencyEvaluator::computeABIDependenciesForModule(swift::ModuleDecl*)"}
// RUN: not --crash %target-swift-frontend -typecheck %s
// RUN: not %target-swift-frontend -typecheck %s
struct a { init? { init!
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// {"signature":"swift::rewriting::performConcreteContraction(llvm::ArrayRef<swift::StructuralRequirement>, llvm::SmallVectorImpl<swift::StructuralRequirement>&, llvm::SmallVectorImpl<swift::rewriting::RequirementError>&, bool)"}
// RUN: not --crash %target-swift-frontend -typecheck %s
// RUN: not %target-swift-frontend -typecheck %s
func a < each b, each c where(repeat(each c each b)) : {
typealias d<each b> = () func e where d<repeat each b> ==
28 changes: 14 additions & 14 deletions validation-test/compiler_crashers_2_fixed/issue-55443.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@

// https://github.com/apple/swift/issues/55443

enum FooString: String { // expected-error {{'FooString' declares raw type 'String', but does not conform to RawRepresentable and conformance could not be synthesized}} expected-note {{add stubs for conformance}}
case bar1 = #file // expected-error {{use of '#file' literal as raw value for enum case is not supported}}
case bar2 = #function // expected-error {{use of '#function' literal as raw value for enum case is not supported}}
case bar3 = #filePath // expected-error {{use of '#filePath' literal as raw value for enum case is not supported}}
case bar4 = #line // expected-error {{cannot convert value of type 'Int' to raw type 'String'}}
case bar5 = #column // expected-error {{cannot convert value of type 'Int' to raw type 'String'}}
case bar6 = #dsohandle // expected-error {{cannot convert value of type 'UnsafeRawPointer' to raw type 'String'}}
enum FooString: String {
case bar1 = #file // expected-error {{raw value for enum case must be a literal}}
case bar2 = #function // expected-error {{raw value for enum case must be a literal}}
case bar3 = #filePath // expected-error {{raw value for enum case must be a literal}}
case bar4 = #line // expected-error {{raw value for enum case must be a literal}}
case bar5 = #column // expected-error {{raw value for enum case must be a literal}}
case bar6 = #dsohandle // expected-error {{raw value for enum case must be a literal}}
}

enum FooInt: Int { // expected-error {{'FooInt' declares raw type 'Int', but does not conform to RawRepresentable and conformance could not be synthesized}} expected-note {{add stubs for conformance}}
case bar1 = #file // expected-error {{cannot convert value of type 'String' to raw type 'Int'}}
case bar2 = #function // expected-error {{cannot convert value of type 'String' to raw type 'Int'}}
case bar3 = #filePath // expected-error {{cannot convert value of type 'String' to raw type 'Int'}}
case bar4 = #line // expected-error {{use of '#line' literal as raw value for enum case is not supported}}
case bar5 = #column // expected-error {{use of '#column' literal as raw value for enum case is not supported}}
case bar6 = #dsohandle // expected-error {{cannot convert value of type 'UnsafeRawPointer' to raw type 'Int'}}
enum FooInt: Int {
case bar1 = #file // expected-error {{raw value for enum case must be a literal}}
case bar2 = #function // expected-error {{raw value for enum case must be a literal}}
case bar3 = #filePath // expected-error {{raw value for enum case must be a literal}}
case bar4 = #line // expected-error {{raw value for enum case must be a literal}}
case bar5 = #column // expected-error {{raw value for enum case must be a literal}}
case bar6 = #dsohandle // expected-error {{raw value for enum case must be a literal}}
}