Skip to content

Commit 59778f8

Browse files
committed
[Parse] Disable support for multiline/extended escaping string literal
in attribute message Strings of diagnostics message processed in EncodedDiagnosticMessage aren't necessarily from parsed Swift source code. That means, they might not have quotes around it. Furthermore, memory around them might not be managed. The logic in 'Lexer::getEncodedStringSegment()' used to cause access violation. For now, disable multiline string literal and extended escaping in string literal for attribute message position. Considering the message might be from Clang, we cannot simply enable this. rdar://problem/44228891
1 parent eb75ad8 commit 59778f8

File tree

5 files changed

+35
-22
lines changed

5 files changed

+35
-22
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1295,7 +1295,11 @@ ERROR(swift_native_objc_runtime_base_must_be_identifier,none,
12951295
"@_swift_native_objc_runtime_base class name must be an identifier", ())
12961296

12971297
ERROR(attr_interpolated_string,none,
1298-
"%0 cannot be an interpolated string literal", (StringRef))
1298+
"'%0' cannot be an interpolated string literal", (StringRef))
1299+
ERROR(attr_multiline_string,none,
1300+
"'%0' cannot be a multiline string literal", (StringRef))
1301+
ERROR(attr_extended_escaping_string,none,
1302+
"'%0' cannot be an extended escaping string literal", (StringRef))
12991303

13001304
ERROR(attr_only_at_non_local_scope, none,
13011305
"attribute '%0' can only be used in a non-local scope", (StringRef))

lib/Parse/Lexer.cpp

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2108,26 +2108,6 @@ StringRef Lexer::getEncodedStringSegment(StringRef Bytes,
21082108
// range check subscripting on the StringRef.
21092109
const char *BytesPtr = Bytes.begin();
21102110

2111-
// Special case when being called from EncodedDiagnosticMessage(...).
2112-
// This allows multiline and delimited strings to work in attributes.
2113-
// The string has already been validated by the initial parse.
2114-
if (IndentToStrip == ~0u && CustomDelimiterLen == ~0u) {
2115-
IndentToStrip = CustomDelimiterLen = 0;
2116-
2117-
// Restore trailing indent removal for multiline.
2118-
const char *Backtrack = BytesPtr - 1;
2119-
if (Backtrack[-1] == '"' && Backtrack[-2] == '"') {
2120-
Backtrack -= 2;
2121-
for (const char *Trailing = Bytes.end() - 1;
2122-
*Trailing == ' ' || *Trailing == '\t'; Trailing--)
2123-
IndentToStrip++;
2124-
}
2125-
2126-
// Restore delimiter if any.
2127-
while (*--Backtrack == '#')
2128-
CustomDelimiterLen++;
2129-
}
2130-
21312111
bool IsEscapedNewline = false;
21322112
while (BytesPtr < Bytes.end()) {
21332113
char CurChar = *BytesPtr++;

lib/Parse/ParseDecl.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,16 @@ bool Parser::parseTopLevel() {
300300
static Optional<StringRef>
301301
getStringLiteralIfNotInterpolated(Parser &P, SourceLoc Loc, const Token &Tok,
302302
StringRef DiagText) {
303+
// FIXME: Support extended escaping / multiline string literal.
304+
if (Tok.getCustomDelimiterLen()) {
305+
P.diagnose(Loc, diag::attr_extended_escaping_string, DiagText);
306+
return None;
307+
}
308+
if (Tok.isMultilineString()) {
309+
P.diagnose(Loc, diag::attr_multiline_string, DiagText);
310+
return None;
311+
}
312+
303313
SmallVector<Lexer::StringSegment, 1> Segments;
304314
P.L->getStringLiteralSegments(Tok, Segments);
305315
if (Segments.size() != 1 ||

lib/Sema/TypeChecker.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2164,7 +2164,7 @@ class EncodedDiagnosticMessage {
21642164
public:
21652165
/// \param S A string with an encoded message
21662166
EncodedDiagnosticMessage(StringRef S)
2167-
: Message(Lexer::getEncodedStringSegment(S, Buf, true, true, ~0, ~0)) {}
2167+
: Message(Lexer::getEncodedStringSegment(S, Buf)) {}
21682168

21692169
/// The unescaped message to display to the user.
21702170
const StringRef Message;

test/Parse/diagnose_availability.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,22 @@ func swiftDeprecatedObsoleted() {}
6262
// expected-warning@-1 {{expected 'introduced', 'deprecated', or 'obsoleted' in 'available' attribute for platform 'swift'}}
6363
func swiftMessage() {}
6464

65+
@available(*, unavailable, message: "\("message")")
66+
// expected-error@-1{{'message' cannot be an interpolated string literal}}
67+
func interpolatedMessage() {}
68+
69+
// expected-error@+1{{'message' cannot be a multiline string literal}}
70+
@available(*, unavailable, message: """
71+
foobar message.
72+
""")
73+
func multilineMessage() {}
74+
75+
// expected-error@+1{{'message' cannot be an extended escaping string literal}}
76+
@available(*, unavailable, message: #"""
77+
foobar message.
78+
"""#)
79+
func extendedEscapedMultilineMessage() {}
80+
81+
// expected-error@+1{{'renamed' cannot be an extended escaping string literal}}
82+
@available(*, unavailable, renamed: #"avialable()"#)
83+
func extenedEscpaedRenamed() {}

0 commit comments

Comments
 (0)