Skip to content

Commit 31066ea

Browse files
committed
[Macros] Disallow self and Self as macro names
We were allowing `self` and `Self` as freestanding macro names, which we don’t want.
1 parent 0fb7f8f commit 31066ea

File tree

5 files changed

+70
-21
lines changed

5 files changed

+70
-21
lines changed

include/swift/Parse/Parser.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,6 +1716,11 @@ class Parser {
17161716

17171717
/// If passed, compound names with empty argument lists are allowed.
17181718
AllowZeroArgCompoundNames = AllowCompoundNames | 1 << 5,
1719+
1720+
/// If passed, \c self and \c Self are allowed as basenames. In a lot of
1721+
/// cases this doesn't actually make sense but we need to accept them for
1722+
/// backwards compatibility.
1723+
AllowLowercaseAndUppercaseSelf = 1 << 6,
17191724
};
17201725
using DeclNameOptions = OptionSet<DeclNameFlag>;
17211726

lib/Parse/ParseDecl.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,8 @@ bool Parser::parseSpecializeAttributeArguments(
850850
loc, diag::attr_specialize_expected_function,
851851
DeclNameFlag::AllowZeroArgCompoundNames |
852852
DeclNameFlag::AllowKeywordsUsingSpecialNames |
853-
DeclNameFlag::AllowOperators);
853+
DeclNameFlag::AllowOperators |
854+
DeclNameFlag::AllowLowercaseAndUppercaseSelf);
854855
}
855856
}
856857
if (ParamLabel == "spiModule") {
@@ -1137,10 +1138,11 @@ Parser::parseImplementsAttribute(SourceLoc AtLoc, SourceLoc Loc) {
11371138
}
11381139

11391140
if (!Status.isErrorOrHasCompletion()) {
1140-
MemberName = parseDeclNameRef(MemberNameLoc,
1141-
diag::attr_implements_expected_member_name,
1141+
MemberName = parseDeclNameRef(
1142+
MemberNameLoc, diag::attr_implements_expected_member_name,
11421143
DeclNameFlag::AllowZeroArgCompoundNames |
1143-
DeclNameFlag::AllowOperators);
1144+
DeclNameFlag::AllowOperators |
1145+
DeclNameFlag::AllowLowercaseAndUppercaseSelf);
11441146
if (!MemberName) {
11451147
Status.setIsParseError();
11461148
}
@@ -1505,7 +1507,8 @@ static bool parseQualifiedDeclName(Parser &P, Diag<> nameParseError,
15051507
original.Loc, nameParseError,
15061508
Parser::DeclNameFlag::AllowZeroArgCompoundNames |
15071509
Parser::DeclNameFlag::AllowKeywordsUsingSpecialNames |
1508-
Parser::DeclNameFlag::AllowOperators);
1510+
Parser::DeclNameFlag::AllowOperators |
1511+
Parser::DeclNameFlag::AllowLowercaseAndUppercaseSelf);
15091512
// The base type is optional, but the final unqualified declaration name is
15101513
// not. If name could not be parsed, return true for error.
15111514
if (!original.Name)
@@ -3207,11 +3210,12 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
32073210
consumeToken(tok::colon);
32083211
{
32093212
DeclNameLoc loc;
3210-
replacedFunction = parseDeclNameRef(loc,
3211-
diag::attr_dynamic_replacement_expected_function,
3213+
replacedFunction = parseDeclNameRef(
3214+
loc, diag::attr_dynamic_replacement_expected_function,
32123215
DeclNameFlag::AllowZeroArgCompoundNames |
3213-
DeclNameFlag::AllowKeywordsUsingSpecialNames |
3214-
DeclNameFlag::AllowOperators);
3216+
DeclNameFlag::AllowKeywordsUsingSpecialNames |
3217+
DeclNameFlag::AllowOperators |
3218+
DeclNameFlag::AllowLowercaseAndUppercaseSelf);
32153219
}
32163220
}
32173221

@@ -3920,8 +3924,9 @@ bool Parser::parseConventionAttributeInternal(
39203924
}
39213925

39223926
DeclNameLoc unusedLoc;
3923-
convention.WitnessMethodProtocol = parseDeclNameRef(unusedLoc,
3924-
diag::convention_attribute_witness_method_expected_protocol, {});
3927+
convention.WitnessMethodProtocol = parseDeclNameRef(
3928+
unusedLoc, diag::convention_attribute_witness_method_expected_protocol,
3929+
DeclNameFlag::AllowLowercaseAndUppercaseSelf);
39253930
}
39263931

39273932
// Parse the ')'. We can't use parseMatchingToken if we're in

lib/Parse/ParseExpr.cpp

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -745,7 +745,8 @@ ParserResult<Expr> Parser::parseExprKeyPathObjC() {
745745
// Parse the sequence of unqualified-names.
746746
ParserStatus status;
747747
SourceLoc LastDotLoc;
748-
DeclNameOptions flags = DeclNameFlag::AllowCompoundNames;
748+
DeclNameOptions flags = DeclNameFlag::AllowCompoundNames |
749+
DeclNameFlag::AllowLowercaseAndUppercaseSelf;
749750
while (true) {
750751
// Handle code completion.
751752
if (Tok.is(tok::code_complete))
@@ -1272,8 +1273,10 @@ Parser::parseExprPostfixSuffix(ParserResult<Expr> Result, bool isExprBasic,
12721273
Diag<> D = isa<SuperRefExpr>(Result.get())
12731274
? diag::expected_identifier_after_super_dot_expr
12741275
: diag::expected_member_name;
1275-
auto Name = parseDeclNameRef(NameLoc, D,
1276-
DeclNameFlag::AllowKeywords | DeclNameFlag::AllowCompoundNames);
1276+
auto Name = parseDeclNameRef(
1277+
NameLoc, D,
1278+
DeclNameFlag::AllowKeywords | DeclNameFlag::AllowCompoundNames |
1279+
DeclNameFlag::AllowLowercaseAndUppercaseSelf);
12771280
if (!Name) {
12781281
SourceRange ErrorRange = Result.get()->getSourceRange();
12791282
ErrorRange.widen(TokLoc);
@@ -1756,7 +1759,9 @@ ParserResult<Expr> Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) {
17561759
}
17571760

17581761
Name = parseDeclNameRef(NameLoc, diag::expected_identifier_after_dot_expr,
1759-
DeclNameFlag::AllowKeywords | DeclNameFlag::AllowCompoundNames);
1762+
DeclNameFlag::AllowKeywords |
1763+
DeclNameFlag::AllowCompoundNames |
1764+
DeclNameFlag::AllowLowercaseAndUppercaseSelf);
17601765
if (!Name)
17611766
return makeParserErrorResult(new (Context) ErrorExpr(DotLoc));
17621767

@@ -2205,7 +2210,9 @@ DeclNameRef Parser::parseDeclNameRef(DeclNameLoc &loc,
22052210
// Consume the base name.
22062211
DeclBaseName baseName;
22072212
SourceLoc baseNameLoc;
2208-
if (Tok.isAny(tok::identifier, tok::kw_Self, tok::kw_self)) {
2213+
if (Tok.is(tok::identifier) ||
2214+
(flags.contains(DeclNameFlag::AllowLowercaseAndUppercaseSelf) &&
2215+
Tok.isAny(tok::kw_Self, tok::kw_self))) {
22092216
Identifier baseNameId;
22102217
baseNameLoc = consumeIdentifier(baseNameId, /*diagnoseDollarPrefix=*/false);
22112218
baseName = baseNameId;
@@ -2266,8 +2273,10 @@ ParserResult<Expr> Parser::parseExprIdentifier() {
22662273

22672274
// Parse the unqualified-decl-name.
22682275
DeclNameLoc loc;
2269-
DeclNameRef name = parseDeclNameRef(loc, diag::expected_expr,
2270-
DeclNameFlag::AllowCompoundNames);
2276+
DeclNameRef name =
2277+
parseDeclNameRef(loc, diag::expected_expr,
2278+
DeclNameFlag::AllowCompoundNames |
2279+
DeclNameFlag::AllowLowercaseAndUppercaseSelf);
22712280

22722281
SmallVector<TypeRepr*, 8> args;
22732282
SourceLoc LAngleLoc, RAngleLoc;
@@ -3123,8 +3132,10 @@ ParserStatus Parser::parseExprList(tok leftTok, tok rightTok,
31233132
Expr *SubExpr = nullptr;
31243133
if (isUnappliedOperator()) {
31253134
DeclNameLoc Loc;
3126-
auto OperName = parseDeclNameRef(Loc, diag::expected_operator_ref,
3127-
DeclNameFlag::AllowOperators);
3135+
auto OperName =
3136+
parseDeclNameRef(Loc, diag::expected_operator_ref,
3137+
DeclNameFlag::AllowOperators |
3138+
DeclNameFlag::AllowLowercaseAndUppercaseSelf);
31283139
if (!OperName) {
31293140
return makeParserError();
31303141
}

lib/Parse/ParseType.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,8 @@ ParserResult<IdentTypeRepr> Parser::parseTypeIdentifier() {
812812
// component.
813813
DeclNameLoc Loc;
814814
DeclNameRef Name =
815-
parseDeclNameRef(Loc, diag::expected_identifier_in_dotted_type, {});
815+
parseDeclNameRef(Loc, diag::expected_identifier_in_dotted_type,
816+
DeclNameFlag::AllowLowercaseAndUppercaseSelf);
816817
if (!Name)
817818
return makeParserError();
818819

test/Macros/macro_self.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %target-swift-frontend -parse %s -verify
2+
3+
@freestanding(expression) // expected-error {{expected expression}}
4+
macro self() = #externalMacro(module: "MacroDefinition", type: "InvalidMacro")
5+
6+
func sync() {}
7+
8+
@freestanding(expression) // expected-error {{expected expression}}
9+
macro Self() = #externalMacro(module: "MacroDefinition", type: "InvalidMacro")
10+
11+
func testSelfAsFreestandingMacro() {
12+
_ = #self // expected-error {{expected a macro identifier for a pound literal expression}}
13+
}
14+
15+
func testCapitalSelfAsFreestandingMacro() {
16+
_ = #Self // expected-error {{expected a macro identifier for a pound literal expression}}
17+
}
18+
19+
func testSelfAsAttachedMacro() {
20+
@self // expected-error {{expected expression}}
21+
struct Foo {}
22+
}
23+
24+
func testCapitalSelfAsAttachedMacro() {
25+
@Self // expected-error {{expected expression}}
26+
struct Foo {}
27+
}

0 commit comments

Comments
 (0)