Skip to content

Commit eb450ee

Browse files
johnno1962rintaro
authored andcommitted
Fix minor bug in #sourceLocation on lex error (#19344)
Fix a minor bug in the implementation of #sourceLocation when the directive is succeeded by token that gives an error during lexing. The error will be reported with the wrong location. This is because lexing of the next token occurs immediately on consuming the last token of the directive which is before the virtual file is set up to have the location take effect. Resolved by moving consumption of directives last token to the end of the function.
1 parent 21654c3 commit eb450ee

File tree

2 files changed

+16
-7
lines changed

2 files changed

+16
-7
lines changed

lib/Parse/ParseDecl.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3583,7 +3583,6 @@ ParserStatus Parser::parseLineDirective(bool isLine) {
35833583

35843584
unsigned StartLine = 0;
35853585
Optional<StringRef> Filename;
3586-
const char *LastTokTextEnd;
35873586
if (!isLine) {
35883587
// #sourceLocation()
35893588
// #sourceLocation(file: "foo", line: 42)
@@ -3640,10 +3639,10 @@ ParserStatus Parser::parseLineDirective(bool isLine) {
36403639
consumeToken(tok::integer_literal);
36413640
}
36423641

3643-
LastTokTextEnd = Tok.getText().end();
3644-
if (parseToken(tok::r_paren, diag::sourceLocation_expected, ")"))
3642+
if (Tok.isNot(tok::r_paren)) {
3643+
diagnose(Tok, diag::sourceLocation_expected, ")");
36453644
return makeParserError();
3646-
3645+
}
36473646
} else { // Legacy #line syntax.
36483647

36493648
// #line\n returns to the main buffer.
@@ -3679,10 +3678,10 @@ ParserStatus Parser::parseLineDirective(bool isLine) {
36793678
"#line");
36803679
if (!Filename.hasValue())
36813680
return makeParserError();
3682-
LastTokTextEnd = Tok.getText().end();
3683-
consumeToken(tok::string_literal);
36843681
}
3685-
3682+
3683+
const char *LastTokTextEnd = Tok.getText().end();
3684+
36863685
// Skip over trailing whitespace and a single \n to the start of the next
36873686
// line.
36883687
while (*LastTokTextEnd == ' ' || *LastTokTextEnd == '\t')
@@ -3703,6 +3702,9 @@ ParserStatus Parser::parseLineDirective(bool isLine) {
37033702
Filename.getValue(), LineOffset);
37043703
assert(isNewFile);(void)isNewFile;
37053704

3705+
// Lexing of next token must be deferred until after virtual file setup.
3706+
consumeToken(isLine ? tok::string_literal : tok::r_paren);
3707+
37063708
InPoundLineEnvironment = true;
37073709
return makeParserSuccess();
37083710
}

test/Parse/line-directive.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %target-typecheck-verify-swift
2+
// RUN: not %target-swift-frontend -c %s 2>&1 | %FileCheck %s
23

34
let x = 0 // We need this because of the #sourceLocation-ends-with-a-newline requirement.
45

@@ -53,3 +54,9 @@ enum E {
5354
case C, D
5455
#sourceLocation()
5556
}
57+
58+
#sourceLocation(file: "sr8772.swift", line: 400)
59+
2., 3
60+
// CHECK: sr8772.swift:400:2: error: expected member name following '.'
61+
// CHECK: sr8772.swift:400:3: error: consecutive statements on a line must be separated by ';'
62+
// CHECK: sr8772.swift:400:3: error: expected expression

0 commit comments

Comments
 (0)