Skip to content

Commit b790eb5

Browse files
committed
[Parser] Improve diagnostics for special platforms in available attribute.
This patch adds warnings when a version number is used on the non-specific '*' platform. In addition, it fixes some misleading warning messages on 'swift' platform. Resolves: SR-8598.
1 parent 76aa3ed commit b790eb5

File tree

3 files changed

+77
-4
lines changed

3 files changed

+77
-4
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,6 +1328,20 @@ ERROR(attr_availability_expected_equal,none,
13281328
ERROR(attr_availability_expected_version,none,
13291329
"expected version number in '%0' attribute", (StringRef))
13301330

1331+
WARNING(attr_availability_swift_platform_expected_option,none,
1332+
"expected '%0' option with a version number for swift platform, "
1333+
"such as 'introduced', 'deprecated', or 'obsoleted'", (StringRef))
1334+
WARNING(attr_availability_swift_platform_deprecated,none,
1335+
"'deprecated' must have a version number for swift platform in '%0' "
1336+
"attribute", (StringRef))
1337+
WARNING(attr_availability_swift_platform_infeasible,none,
1338+
"argument '%0' is infeasible for swift platform in '%1' attribute",
1339+
(StringRef, StringRef))
1340+
1341+
WARNING(attr_availability_nonspecific_platform_unexpected_version,none,
1342+
"unexpected version number for non-specific platform '*' in '%0' "
1343+
"attribute", (StringRef))
1344+
13311345
// autoclosure
13321346
ERROR(attr_autoclosure_expected_r_paren,PointsToFirstBadToken,
13331347
"expected ')' in @autoclosure", ())

lib/Parse/ParseDecl.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -511,10 +511,29 @@ ParserResult<AvailableAttr> Parser::parseExtendedAvailabilitySpecList(
511511
bool SomeVersion = (!Introduced.empty() ||
512512
!Deprecated.empty() ||
513513
!Obsoleted.empty());
514-
if (!PlatformKind.hasValue() &&
515-
Platform == "swift" &&
516-
SomeVersion &&
517-
PlatformAgnostic == PlatformAgnosticAvailabilityKind::None) {
514+
if (!PlatformKind.hasValue() && Platform == "swift") {
515+
if (PlatformAgnostic == PlatformAgnosticAvailabilityKind::Deprecated) {
516+
diagnose(AttrLoc,
517+
diag::attr_availability_swift_platform_deprecated,
518+
AttrName);
519+
return nullptr;
520+
}
521+
if (PlatformAgnostic == PlatformAgnosticAvailabilityKind::Unavailable) {
522+
diagnose(AttrLoc,
523+
diag::attr_availability_swift_platform_infeasible,
524+
"unavailable",
525+
AttrName);
526+
return nullptr;
527+
}
528+
assert(PlatformAgnostic == PlatformAgnosticAvailabilityKind::None);
529+
530+
if (!SomeVersion) {
531+
diagnose(AttrLoc,
532+
diag::attr_availability_swift_platform_expected_option,
533+
AttrName);
534+
return nullptr;
535+
}
536+
518537
PlatformKind = PlatformKind::none;
519538
PlatformAgnostic = PlatformAgnosticAvailabilityKind::SwiftVersionSpecific;
520539
}
@@ -528,6 +547,14 @@ ParserResult<AvailableAttr> Parser::parseExtendedAvailabilitySpecList(
528547
return nullptr;
529548
}
530549

550+
// Warn if any version is specified for non-specific '*' platforms.
551+
if (Platform == "*" && SomeVersion) {
552+
diagnose(AttrLoc,
553+
diag::attr_availability_nonspecific_platform_unexpected_version,
554+
AttrName);
555+
return nullptr;
556+
}
557+
531558
auto Attr = new (Context)
532559
AvailableAttr(AtLoc, SourceRange(AttrLoc, Tok.getLoc()),
533560
PlatformKind.getValue(),

test/Parse/diagnose_availability.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,35 @@ func availableOnMultiplePlatforms() {}
2626
// expected-error@-1 {{'deprecated' can't be combined with shorthand specification 'OSX 10.0'}}
2727
// expected-error@-2 {{expected declaration}}
2828
func twoShorthandsFollowedByDeprecated() {}
29+
30+
31+
// SR-8598: Missing/wrong warning message for '*' or 'swift' platform.
32+
33+
@available(*, deprecated: 4.2)
34+
// expected-warning@-1 {{unexpected version number for non-specific platform '*' in 'available' attribute}}
35+
func allPlatformsDeprecatedVersion() {}
36+
37+
@available(*, deprecated, obsoleted: 4.2)
38+
// expected-warning@-1 {{unexpected version number for non-specific platform '*' in 'available' attribute}}
39+
func allPlatformsDeprecatedAndObsoleted() {}
40+
41+
@available(swift, unavailable)
42+
// expected-warning@-1 {{argument 'unavailable' is infeasible for swift platform in 'available' attribute}}
43+
func swiftUnavailable() {}
44+
45+
@available(swift, unavailable, introduced: 4.2)
46+
// expected-warning@-1 {{argument 'unavailable' is infeasible for swift platform in 'available' attribute}}
47+
func swiftUnavailableIntroduced() {}
48+
49+
@available(swift, deprecated)
50+
// expected-warning@-1 {{'deprecated' must have a version number for swift platform in 'available' attribute}}
51+
func swiftDeprecated() {}
52+
53+
@available(swift, deprecated, obsoleted: 4.2)
54+
// expected-warning@-1 {{'deprecated' must have a version number for swift platform in 'available' attribute}}
55+
func swiftDeprecatedObsoleted() {}
56+
57+
@available(swift, message: "missing valid option")
58+
// expected-warning@-1 {{expected 'available' option with a version number for swift platform, such as 'introduced', 'deprecated', or 'obsoleted'}}
59+
func swiftMessage() {}
60+

0 commit comments

Comments
 (0)