Skip to content

Commit 5bb6f79

Browse files
authored
Merge pull request #64609 from ahoppen/ahoppen/no-self-macros
[Macros] Disallow `self` and `Self` as macro names
2 parents 175e712 + d5a9017 commit 5bb6f79

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
@@ -857,7 +857,8 @@ bool Parser::parseSpecializeAttributeArguments(
857857
loc, diag::attr_specialize_expected_function,
858858
DeclNameFlag::AllowZeroArgCompoundNames |
859859
DeclNameFlag::AllowKeywordsUsingSpecialNames |
860-
DeclNameFlag::AllowOperators);
860+
DeclNameFlag::AllowOperators |
861+
DeclNameFlag::AllowLowercaseAndUppercaseSelf);
861862
}
862863
}
863864
if (ParamLabel == "spiModule") {
@@ -1144,10 +1145,11 @@ Parser::parseImplementsAttribute(SourceLoc AtLoc, SourceLoc Loc) {
11441145
}
11451146

11461147
if (!Status.isErrorOrHasCompletion()) {
1147-
MemberName = parseDeclNameRef(MemberNameLoc,
1148-
diag::attr_implements_expected_member_name,
1148+
MemberName = parseDeclNameRef(
1149+
MemberNameLoc, diag::attr_implements_expected_member_name,
11491150
DeclNameFlag::AllowZeroArgCompoundNames |
1150-
DeclNameFlag::AllowOperators);
1151+
DeclNameFlag::AllowOperators |
1152+
DeclNameFlag::AllowLowercaseAndUppercaseSelf);
11511153
if (!MemberName) {
11521154
Status.setIsParseError();
11531155
}
@@ -1512,7 +1514,8 @@ static bool parseQualifiedDeclName(Parser &P, Diag<> nameParseError,
15121514
original.Loc, nameParseError,
15131515
Parser::DeclNameFlag::AllowZeroArgCompoundNames |
15141516
Parser::DeclNameFlag::AllowKeywordsUsingSpecialNames |
1515-
Parser::DeclNameFlag::AllowOperators);
1517+
Parser::DeclNameFlag::AllowOperators |
1518+
Parser::DeclNameFlag::AllowLowercaseAndUppercaseSelf);
15161519
// The base type is optional, but the final unqualified declaration name is
15171520
// not. If name could not be parsed, return true for error.
15181521
if (!original.Name)
@@ -3214,11 +3217,12 @@ bool Parser::parseNewDeclAttribute(DeclAttributes &Attributes, SourceLoc AtLoc,
32143217
consumeToken(tok::colon);
32153218
{
32163219
DeclNameLoc loc;
3217-
replacedFunction = parseDeclNameRef(loc,
3218-
diag::attr_dynamic_replacement_expected_function,
3220+
replacedFunction = parseDeclNameRef(
3221+
loc, diag::attr_dynamic_replacement_expected_function,
32193222
DeclNameFlag::AllowZeroArgCompoundNames |
3220-
DeclNameFlag::AllowKeywordsUsingSpecialNames |
3221-
DeclNameFlag::AllowOperators);
3223+
DeclNameFlag::AllowKeywordsUsingSpecialNames |
3224+
DeclNameFlag::AllowOperators |
3225+
DeclNameFlag::AllowLowercaseAndUppercaseSelf);
32223226
}
32233227
}
32243228

@@ -3927,8 +3931,9 @@ bool Parser::parseConventionAttributeInternal(
39273931
}
39283932

39293933
DeclNameLoc unusedLoc;
3930-
convention.WitnessMethodProtocol = parseDeclNameRef(unusedLoc,
3931-
diag::convention_attribute_witness_method_expected_protocol, {});
3934+
convention.WitnessMethodProtocol = parseDeclNameRef(
3935+
unusedLoc, diag::convention_attribute_witness_method_expected_protocol,
3936+
DeclNameFlag::AllowLowercaseAndUppercaseSelf);
39323937
}
39333938

39343939
// 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)