mirror of
https://github.com/apple/swift.git
synced 2026-02-27 18:26:24 +01:00
[utils] escape backslashes in diagnostics strings
DiagnosticVerifier lexes the contents of expected diagnostics the same way Swift parses string literals, to allow for escape codes. This makes for problems when backslashes are followed by something that makes for a valid escape. In particular, it reaches an llvm_unreachable if it encounters `\(`, which would create a string interpolation in a string literal.
This commit is contained in:
@@ -42,6 +42,11 @@
|
||||
// RUN: not %target-swift-frontend-verify -I %t -plugin-path %swift-plugin-dir -typecheck %t/unparsed.swift 2>%t/output.txt -Rmacro-expansions
|
||||
// RUN: not %update-verify-tests < %t/output.txt | %FileCheck --check-prefix CHECK-UNPARSED %s
|
||||
|
||||
// RUN: not %target-swift-frontend-verify -load-plugin-library %t/%target-library-name(UnstringifyMacroDefinition) -typecheck %t/escaped.swift 2>%t/output.txt -Rmacro-expansions
|
||||
// RUN: %update-verify-tests < %t/output.txt
|
||||
// RUN: %target-swift-frontend-verify -load-plugin-library %t/%target-library-name(UnstringifyMacroDefinition) -typecheck %t/escaped.swift -Rmacro-expansions
|
||||
// RUN: %diff %t/escaped.swift %t/escaped.swift.expected
|
||||
|
||||
//--- single.swift
|
||||
@attached(peer, names: overloaded)
|
||||
macro unstringifyPeer(_ s: String) =
|
||||
@@ -260,3 +265,43 @@ func bar() {
|
||||
foo(a, &b)
|
||||
}
|
||||
|
||||
//--- escaped.swift
|
||||
@attached(peer, names: overloaded)
|
||||
macro unstringifyPeer(_ s: String) =
|
||||
#externalMacro(module: "UnstringifyMacroDefinition", type: "UnstringifyPeerMacro")
|
||||
|
||||
@unstringifyPeer("""
|
||||
func foo(_ x: Int) {
|
||||
let a = "\\(x)"
|
||||
let b = "\\(x)"
|
||||
}
|
||||
""")
|
||||
// NB: DiagnosticVerifier interprets "\\(x)" as "\(x)"
|
||||
// expected-expansion@+3:30{{
|
||||
// expected-remark@2{{macro content: |let a = "\\(x)"|}}
|
||||
// }}
|
||||
func foo() { let _ = "\(2)" }
|
||||
|
||||
//--- escaped.swift.expected
|
||||
@attached(peer, names: overloaded)
|
||||
macro unstringifyPeer(_ s: String) =
|
||||
#externalMacro(module: "UnstringifyMacroDefinition", type: "UnstringifyPeerMacro")
|
||||
|
||||
// expected-note@+1 6{{in expansion of macro 'unstringifyPeer' on global function 'foo()' here}}
|
||||
@unstringifyPeer("""
|
||||
func foo(_ x: Int) {
|
||||
let a = "\\(x)"
|
||||
let b = "\\(x)"
|
||||
}
|
||||
""")
|
||||
// NB: DiagnosticVerifier interprets "\\(x)" as "\(x)"
|
||||
// expected-expansion@+8:30{{
|
||||
// expected-remark@1{{macro content: |func foo(_ x: Int) {|}}
|
||||
// expected-warning@2{{initialization of immutable value 'a' was never used; consider replacing with assignment to '_' or removing it}}
|
||||
// expected-remark@2{{macro content: | let a = "\\(x)"|}}
|
||||
// expected-warning@3{{initialization of immutable value 'b' was never used; consider replacing with assignment to '_' or removing it}}
|
||||
// expected-remark@3{{macro content: | let b = "\\(x)"|}}
|
||||
// expected-remark@4{{macro content: |}|}}
|
||||
// }}
|
||||
func foo() { let _ = "\(2)" }
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import sys
|
||||
import re
|
||||
from codecs import encode, decode
|
||||
|
||||
DEBUG = False
|
||||
|
||||
@@ -172,7 +173,9 @@ class Diag:
|
||||
if self.category == "expansion":
|
||||
return base_s + "{{"
|
||||
else:
|
||||
return base_s + "{{" + self.diag_content + "}}"
|
||||
# python trivia: raw strings can't end with a backslash
|
||||
escaped_diag_s = self.diag_content.replace("\\", "\\\\")
|
||||
return base_s + "{{" + escaped_diag_s + "}}"
|
||||
|
||||
|
||||
class ExpansionDiagClose:
|
||||
@@ -245,9 +248,12 @@ def parse_diag(line, filename, prefix):
|
||||
count = int(count_s) if count_s else 1
|
||||
line.content = matched_re.sub("{{DIAG}}", s)
|
||||
|
||||
unescaped_diag_s = decode(
|
||||
encode(diag_s, "utf-8", "backslashreplace"), "unicode-escape"
|
||||
)
|
||||
return Diag(
|
||||
check_prefix,
|
||||
diag_s,
|
||||
unescaped_diag_s,
|
||||
category_s,
|
||||
target_line_n,
|
||||
is_absolute,
|
||||
|
||||
Reference in New Issue
Block a user