1 // RUN: %check_clang_tidy -std=c++11,c++14,c++17 %s modernize-raw-string-literal %t -- -config="{CheckOptions: [{key: modernize-raw-string-literal.ReplaceShorterLiterals, value: 1}]}"
2 // FIXME: Fix the checker to work in C++20 mode.
3 
4 char const *const BackSlash("goink\\frob");
5 // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: escaped string literal can be written as a raw string literal [modernize-raw-string-literal]
6 // CHECK-FIXES: {{^}}char const *const BackSlash(R"(goink\frob)");{{$}}
7 
8 char const *const PlainLiteral("plain literal");
9 
10 // Non-printable ASCII characters.
11 char const *const Nul("goink\\\000");
12 char const *const Soh("goink\\\001");
13 char const *const Stx("goink\\\002");
14 char const *const Etx("goink\\\003");
15 char const *const Enq("goink\\\004");
16 char const *const Ack("goink\\\005");
17 char const *const Bell("goink\\\afrob");
18 char const *const BackSpace("goink\\\bfrob");
19 char const *const HorizontalTab("goink\\\tfrob");
20 char const *const NewLine("goink\nfrob");
21 char const *const VerticalTab("goink\\\vfrob");
22 char const *const FormFeed("goink\\\ffrob");
23 char const *const CarraigeReturn("goink\\\rfrob");
24 char const *const So("goink\\\016");
25 char const *const Si("goink\\\017");
26 char const *const Dle("goink\\\020");
27 char const *const Dc1("goink\\\021");
28 char const *const Dc2("goink\\\022");
29 char const *const Dc3("goink\\\023");
30 char const *const Dc4("goink\\\024");
31 char const *const Nak("goink\\\025");
32 char const *const Syn("goink\\\026");
33 char const *const Etb("goink\\\027");
34 char const *const Can("goink\\\030");
35 char const *const Em("goink\\\031");
36 char const *const Sub("goink\\\032");
37 char const *const Esc("goink\\\033");
38 char const *const Fs("goink\\\034");
39 char const *const Gs("goink\\\035");
40 char const *const Rs("goink\\\036");
41 char const *const Us("goink\\\037");
42 char const *const HexNonPrintable("\\\x03");
43 char const *const Delete("\\\177");
44 char const *const MultibyteSnowman("\xE2\x98\x83");
45 // CHECK-FIXES: {{^}}char const *const MultibyteSnowman("\xE2\x98\x83");{{$}}
46 
47 char const *const TrailingSpace("A line \\with space. \n");
48 char const *const TrailingNewLine("A single \\line.\n");
49 char const *const AlreadyRaw(R"(foobie\\bletch)");
50 char const *const UTF8Literal(u8"foobie\\bletch");
51 char const *const UTF8RawLiteral(u8R"(foobie\\bletch)");
52 // TODO: enable these tests once all supported compilers
53 // support char16_t and char32_t (VS2013 does not)
54 // char16_t const *const UTF16Literal(u"foobie\\bletch");
55 // char16_t const *const UTF16RawLiteral(uR"(foobie\\bletch)");
56 // char32_t const *const UTF32Literal(U"foobie\\bletch");
57 // char32_t const *const UTF32RawLiteral(UR"(foobie\\bletch)");
58 wchar_t const *const WideLiteral(L"foobie\\bletch");
59 wchar_t const *const WideRawLiteral(LR"(foobie\\bletch)");
60 
61 char const *const SingleQuote("goink\'frob");
62 // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: {{.*}} can be written as a raw string literal
63 // CHECK-XFIXES: {{^}}char const *const SingleQuote(R"(goink'frob)");{{$}}
64 
65 char const *const DoubleQuote("goink\"frob");
66 // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: {{.*}} can be written as a raw string literal
67 // CHECK-FIXES: {{^}}char const *const DoubleQuote(R"(goink"frob)");{{$}}
68 
69 char const *const QuestionMark("goink\?frob");
70 // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: {{.*}} can be written as a raw string literal
71 // CHECK-FIXES: {{^}}char const *const QuestionMark(R"(goink?frob)");{{$}}
72 
73 char const *const RegEx("goink\\(one|two\\)\\\\\\?.*\\nfrob");
74 // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: {{.*}} can be written as a raw string literal
75 // CHECK-FIXES: {{^}}char const *const RegEx(R"(goink\(one|two\)\\\?.*\nfrob)");{{$}}
76 
77 char const *const Path("C:\\Program Files\\Vendor\\Application\\Application.exe");
78 // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: {{.*}} can be written as a raw string literal
79 // CHECK-FIXES: {{^}}char const *const Path(R"(C:\Program Files\Vendor\Application\Application.exe)");{{$}}
80 
81 char const *const ContainsSentinel("who\\ops)\"");
82 // CHECK-MESSAGES: :[[@LINE-1]]:36: warning: {{.*}} can be written as a raw string literal
83 // CHECK-FIXES: {{^}}char const *const ContainsSentinel(R"lit(who\ops)")lit");{{$}}
84 
85 char const *const ContainsDelim("whoops)\")lit\"");
86 // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: {{.*}} can be written as a raw string literal
87 // CHECK-FIXES: {{^}}char const *const ContainsDelim(R"lit1(whoops)")lit")lit1");{{$}}
88 
89 char const *const OctalPrintable("\100\\");
90 // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: {{.*}} can be written as a raw string literal
91 // CHECK-FIXES: {{^}}char const *const OctalPrintable(R"(@\)");{{$}}
92 
93 char const *const HexPrintable("\x40\\");
94 // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: {{.*}} can be written as a raw string literal
95 // CHECK-FIXES: {{^}}char const *const HexPrintable(R"(@\)");{{$}}
96 
97 char const *const prettyFunction(__PRETTY_FUNCTION__);
98 char const *const function(__FUNCTION__);
99 char const *const func(__func__);
100 
101 #define TRICK(arg_) #arg_
102 char const *const MacroBody = TRICK(foo\\bar);
103 
104 #define HAT(rabbit_) #rabbit_ "foo\\bar"
105 char const *const StringizedMacroArgument = HAT(foo\\bar);
106 
107 #define SUBST(lit_) lit_
108 char const *const MacroArgument = SUBST("foo\\bar");
109 // FIXME: We should be able to replace this string literal macro argument
110 
111 template <typename T>
fn(char const * const Arg)112 void fn(char const *const Arg) {
113   char const *const Str("foo\\bar");
114   // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: {{.*}} can be written as a raw string literal
115   // CHECK-FIXES: {{^}}  char const *const Str(R"(foo\bar)");{{$}}
116 }
117 
118 template <>
fn(char const * const Arg)119 void fn<int>(char const *const Arg) {
120   char const *const Str("foo\\bar");
121   // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: {{.*}} can be written as a raw string literal
122   // CHECK-FIXES: {{^}}  char const *const Str(R"(foo\bar)");{{$}}
123 }
124 
callFn()125 void callFn() {
126   fn<int>("foo\\bar");
127   // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} can be written as a raw string literal
128   // CHECK-FIXES: {{^}}  fn<int>(R"(foo\bar)");{{$}}
129   fn<double>("foo\\bar");
130   // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} can be written as a raw string literal
131   // CHECK-FIXES: {{^}}  fn<double>(R"(foo\bar)");{{$}}
132 }
133