1 // RUN: %check_clang_tidy -check-suffixes=,STRICT \ 2 // RUN: -std=c++23 %s modernize-use-std-print %t -- \ 3 // RUN: -config="{CheckOptions: {modernize-use-std-print.StrictMode: true}}" \ 4 // RUN: -- -isystem %clang_tidy_headers -fexceptions \ 5 // RUN: -DPRI_CMDLINE_MACRO="\"s\"" \ 6 // RUN: -D__PRI_CMDLINE_MACRO="\"s\"" 7 // RUN: %check_clang_tidy -check-suffixes=,NOTSTRICT \ 8 // RUN: -std=c++23 %s modernize-use-std-print %t -- \ 9 // RUN: -config="{CheckOptions: {modernize-use-std-print.StrictMode: false}}" \ 10 // RUN: -- -isystem %clang_tidy_headers -fexceptions \ 11 // RUN: -DPRI_CMDLINE_MACRO="\"s\"" \ 12 // RUN: -D__PRI_CMDLINE_MACRO="\"s\"" 13 #include <cstddef> 14 #include <cstdint> 15 #include <cstdio> 16 // CHECK-FIXES: #include <print> 17 #include <inttypes.h> 18 #include <string.h> 19 #include <string> 20 21 template <typename T> 22 struct iterator { 23 T *operator->(); 24 T &operator*(); 25 }; 26 27 void printf_simple() { 28 printf("Hello"); 29 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 30 // CHECK-FIXES: std::print("Hello"); 31 } 32 33 void printf_newline() { 34 printf("Hello\n"); 35 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 36 // CHECK-FIXES: std::println("Hello"); 37 38 printf("Split" "\n"); 39 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 40 // CHECK-FIXES: std::println("Split"); 41 42 printf("Double\n\n"); 43 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 44 // CHECK-FIXES: std::println("Double\n"); 45 } 46 47 void printf_deceptive_newline() { 48 printf("Hello\\n"); 49 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 50 // CHECK-FIXES: std::print("Hello\\n"); 51 52 printf("Hello\x0a"); 53 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 54 // CHECK-FIXES: std::println("Hello"); 55 } 56 57 void printf_crlf_newline() { 58 printf("Hello\r\n"); 59 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 60 // CHECK-FIXES: std::print("Hello\r\n"); 61 62 printf("Hello\r\\n"); 63 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 64 // CHECK-FIXES: std::print("Hello\r\\n"); 65 } 66 67 // std::print returns nothing, so any callers that use the return 68 // value cannot be automatically translated. 69 int printf_uses_return_value(int choice) { 70 const int i = printf("Return value assigned to variable %d\n", 42); 71 72 extern void accepts_int(int); 73 accepts_int(printf("Return value passed to function %d\n", 42)); 74 75 if (choice == 0) 76 printf("if body %d\n", i); 77 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 78 // CHECK-FIXES: std::println("if body {}", i); 79 else if (choice == 1) 80 printf("else if body %d\n", i); 81 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 82 // CHECK-FIXES: std::println("else if body {}", i); 83 else 84 printf("else body %d\n", i); 85 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 86 // CHECK-FIXES: std::println("else body {}", i); 87 88 if (printf("Return value used as boolean in if statement")) 89 if (printf("Return value used in expression if statement") == 44) 90 if (const int j = printf("Return value used in assignment in if statement")) 91 if (const int k = printf("Return value used with initializer in if statement"); k == 44) 92 ; 93 94 int d = 0; 95 while (printf("%d", d) < 2) 96 ++d; 97 98 while (true) 99 printf("while body %d\n", i); 100 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 101 // CHECK-FIXES: std::println("while body {}", i); 102 103 do 104 printf("do body %d\n", i); 105 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 106 // CHECK-FIXES: std::println("do body {}", i); 107 while (true); 108 109 for (;;) 110 printf("for body %d\n", i); 111 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 112 // CHECK-FIXES: std::println("for body {}", i); 113 114 for (printf("for init statement %d\n", i);;) 115 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 116 // CHECK-FIXES: std::println("for init statement {}", i); 117 ;; 118 119 for (int j = printf("for init statement %d\n", i);;) 120 ;; 121 122 for (; printf("for condition %d\n", i);) 123 ;; 124 125 for (;; printf("for expression %d\n", i)) 126 // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 127 // CHECK-FIXES: std::println("for expression {}", i) 128 ;; 129 130 for (auto C : "foo") 131 printf("ranged-for body %d\n", i); 132 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 133 // CHECK-FIXES: std::println("ranged-for body {}", i); 134 135 switch (1) { 136 case 1: 137 printf("switch case body %d\n", i); 138 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 139 // CHECK-FIXES: std::println("switch case body {}", i); 140 break; 141 default: 142 printf("switch default body %d\n", i); 143 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 144 // CHECK-FIXES: std::println("switch default body {}", i); 145 break; 146 } 147 148 try { 149 printf("try body %d\n", i); 150 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 151 // CHECK-FIXES: std::println("try body {}", i); 152 } catch (int) { 153 printf("catch body %d\n", i); 154 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 155 // CHECK-FIXES: std::println("catch body {}", i); 156 } 157 158 (printf("Parenthesised expression %d\n", i)); 159 // CHECK-MESSAGES: [[@LINE-1]]:4: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 160 // CHECK-FIXES: (std::println("Parenthesised expression {}", i)); 161 162 // Ideally we would convert these two, but the current check doesn't cope with 163 // that. 164 (void)printf("cast to void %d\n", i); 165 // CHECK-MESSAGES-NOT: [[@LINE-1]]:9: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 166 // CHECK-FIXES-NOT: std::println("cast to void {}", i); 167 168 static_cast<void>(printf("static_cast to void %d\n", i)); 169 // CHECK-MESSAGES-NOT: [[@LINE-1]]:9: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 170 // CHECK-FIXES-NOT: std::println("static cast to void {}", i); 171 172 const int x = ({ printf("GCC statement expression using return value immediately %d\n", i); }); 173 const int y = ({ const int y = printf("GCC statement expression using return value immediately %d\n", i); y; }); 174 175 // Ideally we would convert this one, but the current check doesn't cope with 176 // that. 177 ({ printf("GCC statement expression with unused result %d\n", i); }); 178 // CHECK-MESSAGES-NOT: [[@LINE-1]]:6: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 179 // CHECK-FIXES-NOT: std::println("GCC statement expression with unused result {}", i); 180 181 return printf("Return value used in return\n"); 182 } 183 184 int fprintf_uses_return_value(int choice) { 185 const int i = fprintf(stderr, "Return value assigned to variable %d\n", 42); 186 187 extern void accepts_int(int); 188 accepts_int(fprintf(stderr, "Return value passed to function %d\n", 42)); 189 190 if (choice == 0) 191 fprintf(stderr, "if body %d\n", i); 192 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 193 // CHECK-FIXES: std::println(stderr, "if body {}", i); 194 else if (choice == 1) 195 fprintf(stderr, "else if body %d\n", i); 196 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 197 // CHECK-FIXES: std::println(stderr, "else if body {}", i); 198 else 199 fprintf(stderr, "else body %d\n", i); 200 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 201 // CHECK-FIXES: std::println(stderr, "else body {}", i); 202 203 if (fprintf(stderr, "Return value used as boolean in if statement")) 204 if (fprintf(stderr, "Return value used in expression if statement") == 44) 205 if (const int j = fprintf(stderr, "Return value used in assignment in if statement")) 206 if (const int k = fprintf(stderr, "Return value used with initializer in if statement"); k == 44) 207 ; 208 209 int d = 0; 210 while (fprintf(stderr, "%d", d) < 2) 211 ++d; 212 213 while (true) 214 fprintf(stderr, "while body %d\n", i); 215 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 216 // CHECK-FIXES: std::println(stderr, "while body {}", i); 217 218 do 219 fprintf(stderr, "do body %d\n", i); 220 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 221 // CHECK-FIXES: std::println(stderr, "do body {}", i); 222 while (true); 223 224 for (;;) 225 fprintf(stderr, "for body %d\n", i); 226 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 227 // CHECK-FIXES: std::println(stderr, "for body {}", i); 228 229 for (fprintf(stderr, "for init statement %d\n", i);;) 230 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 231 // CHECK-FIXES: std::println(stderr, "for init statement {}", i); 232 ;; 233 234 for (int j = fprintf(stderr, "for init statement %d\n", i);;) 235 ;; 236 237 for (; fprintf(stderr, "for condition %d\n", i);) 238 ;; 239 240 for (;; fprintf(stderr, "for expression %d\n", i)) 241 // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 242 // CHECK-FIXES: std::println(stderr, "for expression {}", i) 243 ;; 244 245 for (auto C : "foo") 246 fprintf(stderr, "ranged-for body %d\n", i); 247 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 248 // CHECK-FIXES: std::println(stderr, "ranged-for body {}", i); 249 250 switch (1) { 251 case 1: 252 fprintf(stderr, "switch case body %d\n", i); 253 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 254 // CHECK-FIXES: std::println(stderr, "switch case body {}", i); 255 break; 256 default: 257 fprintf(stderr, "switch default body %d\n", i); 258 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 259 // CHECK-FIXES: std::println(stderr, "switch default body {}", i); 260 break; 261 } 262 263 try { 264 fprintf(stderr, "try body %d\n", i); 265 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 266 // CHECK-FIXES: std::println(stderr, "try body {}", i); 267 } catch (int) { 268 fprintf(stderr, "catch body %d\n", i); 269 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 270 // CHECK-FIXES: std::println(stderr, "catch body {}", i); 271 } 272 273 274 (printf("Parenthesised expression %d\n", i)); 275 // CHECK-MESSAGES: [[@LINE-1]]:4: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 276 // CHECK-FIXES: (std::println("Parenthesised expression {}", i)); 277 278 // Ideally we would convert these two, but the current check doesn't cope with 279 // that. 280 (void)fprintf(stderr, "cast to void %d\n", i); 281 // CHECK-MESSAGES-NOT: [[@LINE-1]]:9: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 282 // CHECK-FIXES-NOT: std::println(stderr, "cast to void {}", i); 283 284 static_cast<void>(fprintf(stderr, "static_cast to void %d\n", i)); 285 // CHECK-MESSAGES-NOT: [[@LINE-1]]:9: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 286 // CHECK-FIXES-NOT: std::println(stderr, "static cast to void {}", i); 287 288 const int x = ({ fprintf(stderr, "GCC statement expression using return value immediately %d\n", i); }); 289 const int y = ({ const int y = fprintf(stderr, "GCC statement expression using return value immediately %d\n", i); y; }); 290 291 // Ideally we would convert this one, but the current check doesn't cope with 292 // that. 293 ({ fprintf(stderr, "GCC statement expression with unused result %d\n", i); }); 294 // CHECK-MESSAGES-NOT: [[@LINE-1]]:6: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 295 // CHECK-FIXES-NOT: std::println("GCC statement expression with unused result {}", i); 296 297 return fprintf(stderr, "Return value used in return\n"); 298 } 299 300 void fprintf_simple() { 301 fprintf(stderr, "Hello"); 302 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'fprintf' [modernize-use-std-print] 303 // CHECK-FIXES: std::print(stderr, "Hello"); 304 } 305 306 void std_printf_simple() { 307 std::printf("std::Hello"); 308 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 309 // CHECK-FIXES: std::print("std::Hello"); 310 } 311 312 void printf_escape() { 313 printf("before \t"); 314 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 315 // CHECK-FIXES: std::print("before \t"); 316 317 printf("\n after"); 318 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 319 // CHECK-FIXES: std::print("\n after"); 320 321 printf("before \a after"); 322 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 323 // CHECK-FIXES: std::print("before \a after"); 324 325 printf("Bell\a%dBackspace\bFF%s\fNewline\nCR\rTab\tVT\vEscape\x1b\x07%d", 42, "string", 99); 326 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 327 // CHECK-FIXES: std::print("Bell\a{}Backspace\bFF{}\fNewline\nCR\rTab\tVT\vEscape\x1b\a{}", 42, "string", 99); 328 329 printf("not special \x1b\x01\x7f"); 330 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 331 // CHECK-FIXES: std::print("not special \x1b\x01\x7f"); 332 } 333 334 void printf_percent() { 335 printf("before %%"); 336 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 337 // CHECK-FIXES: std::print("before %"); 338 339 printf("%% after"); 340 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 341 // CHECK-FIXES: std::print("% after"); 342 343 printf("before %% after"); 344 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 345 // CHECK-FIXES: std::print("before % after"); 346 347 printf("Hello %% and another %%"); 348 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 349 // CHECK-FIXES: std::print("Hello % and another %"); 350 351 printf("Not a string %%s"); 352 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 353 // CHECK-FIXES: std::print("Not a string %s"); 354 } 355 356 void printf_curlies() { 357 printf("%d {}", 42); 358 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 359 // CHECK-FIXES: std::print("{} {{[{][{]}}}}", 42); 360 361 printf("{}"); 362 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 363 // CHECK-FIXES: std::print("{{[{][{]}}}}"); 364 } 365 366 void printf_unsupported_format_specifiers() { 367 int pos; 368 printf("%d %n %d\n", 42, &pos, 72); 369 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unable to use 'std::println' instead of 'printf' because '%n' is not supported in format string [modernize-use-std-print] 370 371 printf("Error %m\n"); 372 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unable to use 'std::println' instead of 'printf' because '%m' is not supported in format string [modernize-use-std-print] 373 } 374 375 void printf_not_string_literal(const char *fmt) { 376 // We can't convert the format string if it's not a literal 377 printf(fmt, 42); 378 } 379 380 void printf_inttypes_ugliness() { 381 // The one advantage of the checker seeing the token pasted version of the 382 // format string is that we automatically cope with the horrendously-ugly 383 // inttypes.h macros! 384 int64_t u64 = 42; 385 uintmax_t umax = 4242; 386 printf("uint64:%" PRId64 " uintmax:%" PRIuMAX "\n", u64, umax); 387 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 388 // CHECK-FIXES: std::println("uint64:{} uintmax:{}", u64, umax); 389 } 390 391 void printf_raw_string() { 392 // This one doesn't require the format string to be changed, so it stays intact 393 printf(R"(First\Second)"); 394 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 395 // CHECK-FIXES: std::print(R"(First\Second)"); 396 397 // This one does require the format string to be changed, so unfortunately it 398 // gets reformatted as a normal string. 399 printf(R"(First %d\Second)", 42); 400 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 401 // CHECK-FIXES: std::print("First {}\\Second", 42); 402 } 403 404 void printf_integer_d() { 405 const bool b = true; 406 // The "d" type is necessary here for compatibility with printf since 407 // std::print will print booleans as "true" or "false". 408 printf("Integer %d from bool\n", b); 409 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 410 // CHECK-FIXES: std::println("Integer {:d} from bool", b); 411 412 // The "d" type is necessary here for compatibility with printf since 413 // std::print will print booleans as "true" or "false". 414 printf("Integer %i from bool\n", b); 415 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 416 // CHECK-FIXES: std::println("Integer {:d} from bool", b); 417 418 // The 'd' is always necessary if we pass a char since otherwise the 419 // parameter will be formatted as a character. In StrictMode, the 420 // cast is always necessary to maintain the printf behaviour since 421 // char may be unsigned, but this also means that the 'd' is not 422 // necessary. 423 const char c = 'A'; 424 printf("Integers %d %hhd from char\n", c, c); 425 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 426 // CHECK-FIXES-NOTSTRICT: std::println("Integers {:d} {:d} from char", c, c); 427 // CHECK-FIXES-STRICT: std::println("Integers {} {} from char", static_cast<signed char>(c), static_cast<signed char>(c)); 428 429 printf("Integers %i %hhi from char\n", c, c); 430 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 431 // CHECK-FIXES-NOTSTRICT: std::println("Integers {:d} {:d} from char", c, c); 432 // CHECK-FIXES-STRICT: std::println("Integers {} {} from char", static_cast<signed char>(c), static_cast<signed char>(c)); 433 434 const signed char sc = 'A'; 435 printf("Integers %d %hhd from signed char\n", sc, sc); 436 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 437 // CHECK-FIXES: std::println("Integers {} {} from signed char", sc, sc); 438 439 printf("Integers %i %hhi from signed char\n", sc, sc); 440 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 441 // CHECK-FIXES: std::println("Integers {} {} from signed char", sc, sc); 442 443 const unsigned char uc = 'A'; 444 printf("Integers %d %hhd from unsigned char\n", uc, uc); 445 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 446 // CHECK-FIXES-NOTSTRICT: std::println("Integers {} {} from unsigned char", uc, uc); 447 // CHECK-FIXES-STRICT: std::println("Integers {} {} from unsigned char", static_cast<signed char>(uc), static_cast<signed char>(uc)); 448 449 printf("Integers %i %hhi from unsigned char\n", uc, uc); 450 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 451 // CHECK-FIXES-NOTSTRICT: std::println("Integers {} {} from unsigned char", uc, uc); 452 // CHECK-FIXES-STRICT: std::println("Integers {} {} from unsigned char", static_cast<signed char>(uc), static_cast<signed char>(uc)); 453 454 const int8_t i8 = 42; 455 printf("Integer %" PRIi8 " from int8_t\n", i8); 456 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 457 // CHECK-FIXES: std::println("Integer {} from int8_t", i8); 458 459 const int_fast8_t if8 = 42; 460 printf("Integer %" PRIiFAST8 " from int_fast8_t\n", if8); 461 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 462 // CHECK-FIXES: std::println("Integer {} from int_fast8_t", if8); 463 464 const int_least8_t il8 = 42; 465 printf("Integer %" PRIiFAST8 " from int_least8_t\n", il8); 466 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 467 // CHECK-FIXES: std::println("Integer {} from int_least8_t", il8); 468 469 const uint8_t u8 = 42U; 470 const std::uint8_t su8 = u8; 471 printf("Integers %" PRIi8 " and %" PRId8 " from uint8_t\n", u8, su8); 472 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 473 // CHECK-FIXES-NOTSTRICT: std::println("Integers {} and {} from uint8_t", u8, su8); 474 // CHECK-FIXES-STRICT: std::println("Integers {} and {} from uint8_t", static_cast<int8_t>(u8), static_cast<std::int8_t>(su8)); 475 476 const uint_fast8_t uf8 = 42U; 477 printf("Integer %" PRIiFAST8 " from uint_fast8_t\n", uf8); 478 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 479 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from uint_fast8_t", uf8); 480 // CHECK-FIXES-STRICT: std::println("Integer {} from uint_fast8_t", static_cast<int_fast8_t>(uf8)); 481 482 const uint_least8_t ul8 = 42U; 483 printf("Integer %" PRIiLEAST8 " from uint_least8_t\n", ul8); 484 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 485 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from uint_least8_t", ul8); 486 // CHECK-FIXES-STRICT: std::println("Integer {} from uint_least8_t", static_cast<int_least8_t>(ul8)); 487 488 const short s = 42; 489 printf("Integer %hd from short\n", s); 490 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 491 // CHECK-FIXES: std::println("Integer {} from short", s); 492 493 printf("Integer %hi from short\n", s); 494 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 495 // CHECK-FIXES: std::println("Integer {} from short", s); 496 497 const unsigned short us = 42U; 498 printf("Integer %hd from unsigned short\n", us); 499 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 500 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned short", us); 501 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned short", static_cast<short>(us)); 502 503 printf("Integer %hi from unsigned short\n", us); 504 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 505 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned short", us); 506 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned short", static_cast<short>(us)); 507 508 const int i = 42; 509 printf("Integer %d from integer\n", i); 510 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 511 // CHECK-FIXES: std::println("Integer {} from integer", i); 512 513 printf("Integer %i from integer\n", i); 514 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 515 // CHECK-FIXES: std::println("Integer {} from integer", i); 516 517 const unsigned int ui = 42U; 518 printf("Integer %d from unsigned integer\n", ui); 519 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 520 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned integer", ui); 521 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned integer", static_cast<int>(ui)); 522 523 printf("Integer %i from unsigned integer\n", ui); 524 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 525 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned integer", ui); 526 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned integer", static_cast<int>(ui)); 527 528 const long l = 42L; 529 printf("Integer %ld from long\n", l); 530 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 531 // CHECK-FIXES: std::println("Integer {} from long", l); 532 533 printf("Integer %li from long\n", l); 534 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 535 // CHECK-FIXES: std::println("Integer {} from long", l); 536 537 const unsigned long ul = 42UL; 538 printf("Integer %ld from unsigned long\n", ul); 539 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 540 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned long", ul); 541 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned long", static_cast<long>(ul)); 542 543 printf("Integer %li from unsigned long\n", ul); 544 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 545 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned long", ul); 546 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned long", static_cast<long>(ul)); 547 548 const long long ll = 42LL; 549 printf("Integer %lld from long long\n", ll); 550 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 551 // CHECK-FIXES: std::println("Integer {} from long long", ll); 552 553 printf("Integer %lli from long long\n", ll); 554 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 555 // CHECK-FIXES: std::println("Integer {} from long long", ll); 556 557 const unsigned long long ull = 42ULL; 558 printf("Integer %lld from unsigned long long\n", ull); 559 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 560 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned long long", ull); 561 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned long long", static_cast<long long>(ull)); 562 563 printf("Integer %lli from unsigned long long\n", ull); 564 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 565 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned long long", ull); 566 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned long long", static_cast<long long>(ull)); 567 568 const intmax_t im = 42; 569 const std::intmax_t sim = im; 570 printf("Integers %jd and %jd from intmax_t\n", im, sim); 571 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 572 // CHECK-FIXES: std::println("Integers {} and {} from intmax_t", im, sim); 573 574 printf("Integers %ji and %ji from intmax_t\n", im, sim); 575 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 576 // CHECK-FIXES: std::println("Integers {} and {} from intmax_t", im, sim); 577 578 const uintmax_t uim = 42; 579 const std::uintmax_t suim = uim; 580 printf("Integers %jd and %jd from uintmax_t\n", uim, suim); 581 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 582 // CHECK-FIXES-NOTSTRICT: std::println("Integers {} and {} from uintmax_t", uim, suim); 583 // CHECK-FIXES-STRICT: std::println("Integers {} and {} from uintmax_t", static_cast<intmax_t>(uim), static_cast<std::intmax_t>(suim)); 584 585 printf("Integer %ji from intmax_t\n", uim); 586 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 587 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from intmax_t", uim); 588 // CHECK-FIXES-STRICT: std::println("Integer {} from intmax_t", static_cast<intmax_t>(uim)); 589 590 const int ai[] = { 0, 1, 2, 3}; 591 const ptrdiff_t pd = &ai[3] - &ai[0]; 592 const std::ptrdiff_t spd = pd; 593 printf("Integers %td and %td from ptrdiff_t\n", pd, spd); 594 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 595 // CHECK-FIXES: std::println("Integers {} and {} from ptrdiff_t", pd, spd); 596 597 printf("Integers %ti and %ti from ptrdiff_t\n", pd, spd); 598 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 599 // CHECK-FIXES: std::println("Integers {} and {} from ptrdiff_t", pd, spd); 600 601 const size_t z = 42UL; 602 const std::size_t sz = z; 603 printf("Integers %zd and %zd from size_t\n", z, sz); 604 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 605 // CHECK-FIXES-NOTSTRICT: std::println("Integers {} and {} from size_t", z, sz); 606 // CHECK-FIXES-STRICT: std::println("Integers {} and {} from size_t", static_cast<ssize_t>(z), static_cast<std::ssize_t>(sz)); 607 } 608 609 void printf_integer_u() 610 { 611 const bool b = true; 612 // The "d" type is necessary here for compatibility with printf since 613 // std::print will print booleans as "true" or "false". 614 printf("Unsigned integer %u from bool\n", b); 615 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 616 // CHECK-FIXES: std::println("Unsigned integer {:d} from bool", b); 617 618 const char c = 'A'; 619 printf("Unsigned integer %hhu from char\n", c); 620 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 621 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {:d} from char", c); 622 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from char", static_cast<unsigned char>(c)); 623 624 const signed char sc = 'A'; 625 printf("Unsigned integer %hhu from signed char\n", sc); 626 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 627 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from signed char", sc); 628 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from signed char", static_cast<unsigned char>(sc)); 629 630 printf("Unsigned integer %u from signed char\n", sc); 631 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 632 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from signed char", sc); 633 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from signed char", static_cast<unsigned char>(sc)); 634 635 const unsigned char uc = 'A'; 636 printf("Unsigned integer %hhu from unsigned char\n", uc); 637 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 638 // CHECK-FIXES: std::println("Unsigned integer {} from unsigned char", uc); 639 640 printf("Unsigned integer %u from unsigned char\n", uc); 641 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 642 // CHECK-FIXES: std::println("Unsigned integer {} from unsigned char", uc); 643 644 const int8_t i8 = 42; 645 printf("Unsigned integer %" PRIu8 " from int8_t\n", i8); 646 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 647 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from int8_t", i8); 648 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from int8_t", static_cast<uint8_t>(i8)); 649 650 const int_fast8_t if8 = 42; 651 printf("Unsigned integer %" PRIuFAST8 " from int_fast8_t\n", if8); 652 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 653 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from int_fast8_t", if8); 654 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from int_fast8_t", static_cast<uint_fast8_t>(if8)); 655 656 const int_least8_t il8 = 42; 657 printf("Unsigned integer %" PRIuFAST8 " from int_least8_t\n", il8); 658 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 659 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from int_least8_t", il8); 660 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from int_least8_t", static_cast<uint_least8_t>(il8)); 661 662 const uint8_t u8 = 42U; 663 printf("Unsigned integer %" PRIu8 " from uint8_t\n", u8); 664 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 665 // CHECK-FIXES: std::println("Unsigned integer {} from uint8_t", u8); 666 667 const uint_fast8_t uf8 = 42U; 668 printf("Unsigned integer %" PRIuFAST8 " from uint_fast8_t\n", uf8); 669 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 670 // CHECK-FIXES: std::println("Unsigned integer {} from uint_fast8_t", uf8); 671 672 const uint_least8_t ul8 = 42U; 673 printf("Unsigned integer %" PRIuLEAST8 " from uint_least8_t\n", ul8); 674 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 675 // CHECK-FIXES: std::println("Unsigned integer {} from uint_least8_t", ul8); 676 677 const short s = 42; 678 printf("Unsigned integer %hu from short\n", s); 679 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 680 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from short", s); 681 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from short", static_cast<unsigned short>(s)); 682 683 const unsigned short us = 42U; 684 printf("Unsigned integer %hu from unsigned short\n", us); 685 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 686 // CHECK-FIXES: std::println("Unsigned integer {} from unsigned short", us); 687 688 const int i = 42; 689 printf("Unsigned integer %u from signed integer\n", i); 690 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 691 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from signed integer", i); 692 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from signed integer", static_cast<unsigned int>(i)); 693 694 const unsigned int ui = 42U; 695 printf("Unsigned integer %u from unsigned integer\n", ui); 696 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 697 // CHECK-FIXES: std::println("Unsigned integer {} from unsigned integer", ui); 698 699 const long l = 42L; 700 printf("Unsigned integer %u from signed long\n", l); 701 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 702 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from signed long", l); 703 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from signed long", static_cast<unsigned long>(l)); 704 705 const unsigned long ul = 42UL; 706 printf("Unsigned integer %lu from unsigned long\n", ul); 707 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 708 // CHECK-FIXES: std::println("Unsigned integer {} from unsigned long", ul); 709 710 const long long ll = 42LL; 711 printf("Unsigned integer %llu from long long\n", ll); 712 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 713 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from long long", ll); 714 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from long long", static_cast<unsigned long long>(ll)); 715 716 const unsigned long long ull = 42ULL; 717 printf("Unsigned integer %llu from unsigned long long\n", ull); 718 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 719 // CHECK-FIXES: std::println("Unsigned integer {} from unsigned long long", ull); 720 721 const intmax_t im = 42; 722 const std::intmax_t sim = im; 723 printf("Unsigned integers %ju and %ju from intmax_t\n", im, sim); 724 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 725 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integers {} and {} from intmax_t", im, sim); 726 // CHECK-FIXES-STRICT: std::println("Unsigned integers {} and {} from intmax_t", static_cast<uintmax_t>(im), static_cast<std::uintmax_t>(sim)); 727 728 const uintmax_t uim = 42U; 729 const std::uintmax_t suim = uim; 730 printf("Unsigned integers %ju and %ju from uintmax_t\n", uim, suim); 731 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 732 // CHECK-FIXES: std::println("Unsigned integers {} and {} from uintmax_t", uim, suim); 733 734 const int ai[] = { 0, 1, 2, 3}; 735 const ptrdiff_t pd = &ai[3] - &ai[0]; 736 const std::ptrdiff_t spd = pd; 737 printf("Unsigned integers %tu and %tu from ptrdiff_t\n", pd, spd); 738 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 739 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integers {} and {} from ptrdiff_t", pd, spd); 740 // CHECK-FIXES-STRICT: std::println("Unsigned integers {} and {} from ptrdiff_t", static_cast<size_t>(pd), static_cast<std::size_t>(spd)); 741 742 const size_t z = 42U; 743 const std::size_t sz = z; 744 printf("Unsigned integers %zu and %zu from size_t\n", z, sz); 745 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 746 // CHECK-FIXES: std::println("Unsigned integers {} and {} from size_t", z, sz); 747 } 748 749 // This checks that we get the argument offset right with the extra FILE * argument 750 void fprintf_integer() { 751 fprintf(stderr, "Integer %d from integer\n", 42); 752 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 753 // CHECK-FIXES: std::println(stderr, "Integer {} from integer", 42); 754 755 fprintf(stderr, "Integer %i from integer\n", 65); 756 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 757 // CHECK-FIXES: std::println(stderr, "Integer {} from integer", 65); 758 759 fprintf(stderr, "Integer %i from char\n", 'A'); 760 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 761 // CHECK-FIXES-NOTSTRICT: std::println(stderr, "Integer {:d} from char", 'A'); 762 // CHECK-FIXES-STRICT: std::println(stderr, "Integer {} from char", static_cast<signed char>('A')); 763 764 fprintf(stderr, "Integer %d from char\n", 'A'); 765 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 766 // CHECK-FIXES-NOTSTRICT: std::println(stderr, "Integer {:d} from char", 'A'); 767 // CHECK-FIXES-STRICT: std::println(stderr, "Integer {} from char", static_cast<signed char>('A')); 768 } 769 770 void printf_char() { 771 const char c = 'A'; 772 printf("Char %c from char\n", c); 773 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 774 // CHECK-FIXES: std::println("Char {} from char", c); 775 776 const signed char sc = 'A'; 777 printf("Char %c from signed char\n", sc); 778 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 779 // CHECK-FIXES: std::println("Char {:c} from signed char", sc); 780 781 const unsigned char uc = 'A'; 782 printf("Char %c from unsigned char\n", uc); 783 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 784 // CHECK-FIXES: std::println("Char {:c} from unsigned char", uc); 785 786 const int i = 65; 787 printf("Char %c from integer\n", i); 788 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 789 // CHECK-FIXES: std::println("Char {:c} from integer", i); 790 791 const unsigned int ui = 65; 792 printf("Char %c from unsigned integer\n", ui); 793 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 794 // CHECK-FIXES: std::println("Char {:c} from unsigned integer", ui); 795 796 const unsigned long long ull = 65; 797 printf("Char %c from unsigned long long\n", ull); 798 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 799 // CHECK-FIXES: std::println("Char {:c} from unsigned long long", ull); 800 } 801 802 void printf_bases() { 803 printf("Hex %lx\n", 42L); 804 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 805 // CHECK-FIXES: std::println("Hex {:x}", 42L); 806 807 printf("HEX %X\n", 42); 808 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 809 // CHECK-FIXES: std::println("HEX {:X}", 42); 810 811 printf("Oct %lo\n", 42L); 812 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 813 // CHECK-FIXES: std::println("Oct {:o}", 42L); 814 } 815 816 void printf_alternative_forms() { 817 printf("Hex %#lx\n", 42L); 818 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 819 // CHECK-FIXES: std::println("Hex {:#x}", 42L); 820 821 printf("HEX %#X\n", 42); 822 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 823 // CHECK-FIXES: std::println("HEX {:#X}", 42); 824 825 printf("Oct %#lo\n", 42L); 826 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 827 // CHECK-FIXES: std::println("Oct {:#o}", 42L); 828 829 printf("Double %#f %#F\n", -42.0, -42.0); 830 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 831 // CHECK-FIXES: std::println("Double {:#f} {:#F}", -42.0, -42.0); 832 833 printf("Double %#g %#G\n", -42.0, -42.0); 834 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 835 // CHECK-FIXES: std::println("Double {:#g} {:#G}", -42.0, -42.0); 836 837 printf("Double %#e %#E\n", -42.0, -42.0); 838 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 839 // CHECK-FIXES: std::println("Double {:#e} {:#E}", -42.0, -42.0); 840 841 printf("Double %#a %#A\n", -42.0, -42.0); 842 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 843 // CHECK-FIXES: std::println("Double {:#a} {:#A}", -42.0, -42.0); 844 845 // Characters don't have an alternate form 846 printf("Char %#c\n", 'A'); 847 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 848 // CHECK-FIXES: std::println("Char {}", 'A'); 849 850 // Strings don't have an alternate form 851 printf("Char %#c\n", 'A'); 852 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 853 // CHECK-FIXES: std::println("Char {}", 'A'); 854 } 855 856 void printf_string() { 857 printf("Hello %s after\n", "Goodbye"); 858 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 859 // CHECK-FIXES: std::println("Hello {} after", "Goodbye"); 860 861 // std::print can't print signed char strings. 862 const signed char *sstring = reinterpret_cast<const signed char *>("ustring"); 863 printf("signed char string %s\n", sstring); 864 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 865 // CHECK-FIXES: std::println("signed char string {}", reinterpret_cast<const char *>(sstring)); 866 867 // std::print can't print unsigned char strings. 868 const unsigned char *ustring = reinterpret_cast<const unsigned char *>("ustring"); 869 printf("unsigned char string %s\n", ustring); 870 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 871 // CHECK-FIXES: std::println("unsigned char string {}", reinterpret_cast<const char *>(ustring)); 872 } 873 874 void printf_float() { 875 // If the type is not specified then either f or e will be used depending on 876 // whichever is shorter. This means that it is necessary to be specific to 877 // maintain compatibility with printf. 878 879 // TODO: Should we force a cast here, since printf will promote to double 880 // automatically, but std::format will not, which could result in different 881 // output? 882 883 const float f = 42.0F; 884 printf("Hello %f after\n", f); 885 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 886 // CHECK-FIXES: std::println("Hello {:f} after", f); 887 888 printf("Hello %g after\n", f); 889 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 890 // CHECK-FIXES: std::println("Hello {:g} after", f); 891 892 printf("Hello %e after\n", f); 893 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 894 // CHECK-FIXES: std::println("Hello {:e} after", f); 895 } 896 897 void printf_double() { 898 // If the type is not specified then either f or e will be used depending on 899 // whichever is shorter. This means that it is necessary to be specific to 900 // maintain compatibility with printf. 901 902 const double d = 42.0; 903 printf("Hello %f after\n", d); 904 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 905 // CHECK-FIXES: std::println("Hello {:f} after", d); 906 907 printf("Hello %g after\n", d); 908 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 909 // CHECK-FIXES: std::println("Hello {:g} after", d); 910 911 printf("Hello %e after\n", d); 912 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 913 // CHECK-FIXES: std::println("Hello {:e} after", d); 914 } 915 916 void printf_long_double() { 917 // If the type is not specified then either f or e will be used depending on 918 // whichever is shorter. This means that it is necessary to be specific to 919 // maintain compatibility with printf. 920 921 const long double ld = 42.0L; 922 printf("Hello %Lf after\n", ld); 923 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 924 // CHECK-FIXES: std::println("Hello {:f} after", ld); 925 926 printf("Hello %g after\n", ld); 927 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 928 // CHECK-FIXES: std::println("Hello {:g} after", ld); 929 930 printf("Hello %e after\n", ld); 931 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 932 // CHECK-FIXES: std::println("Hello {:e} after", ld); 933 } 934 935 void printf_pointer() { 936 int i; 937 double j; 938 printf("Int* %p %s %p\n", &i, "Double*", &j); 939 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 940 // CHECK-FIXES: std::println("Int* {} {} {}", static_cast<const void *>(&i), "Double*", static_cast<const void *>(&j)); 941 942 printf("%p\n", nullptr); 943 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 944 // CHECK-FIXES: std::println("{}", nullptr); 945 946 const auto np = nullptr; 947 printf("%p\n", np); 948 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 949 // CHECK-FIXES: std::println("{}", np); 950 951 // NULL isn't a pointer, so std::print needs some help. 952 printf("%p\n", NULL); 953 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 954 // CHECK-FIXES: std::println("{}", static_cast<const void *>(NULL)); 955 956 printf("%p\n", 42); 957 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 958 // CHECK-FIXES: std::println("{}", static_cast<const void *>(42)); 959 960 // If we already have a void pointer then no cast is required. 961 printf("%p\n", reinterpret_cast<const void *>(44)); 962 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 963 // CHECK-FIXES: std::println("{}", reinterpret_cast<const void *>(44)); 964 965 const void *p; 966 printf("%p\n", p); 967 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 968 // CHECK-FIXES: std::println("{}", p); 969 970 // But a pointer to a pointer to void does need a cast 971 const void **pp; 972 printf("%p\n", pp); 973 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 974 // CHECK-FIXES: std::println("{}", static_cast<const void *>(pp)); 975 976 printf("%p\n", printf_pointer); 977 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 978 // CHECK-FIXES: std::println("{}", static_cast<const void *>(printf_pointer)); 979 } 980 981 class AClass 982 { 983 int member; 984 985 void printf_this_pointer() 986 { 987 printf("%p\n", this); 988 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 989 // CHECK-FIXES: std::println("{}", static_cast<const void *>(this)); 990 } 991 992 void printf_pointer_to_member_function() 993 { 994 printf("%p\n", &AClass::printf_pointer_to_member_function); 995 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 996 // CHECK-FIXES: std::println("{}", static_cast<const void *>(&AClass::printf_pointer_to_member_function)); 997 } 998 999 void printf_pointer_to_member_variable() 1000 { 1001 printf("%p\n", &AClass::member); 1002 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1003 // CHECK-FIXES: std::println("{}", static_cast<const void *>(&AClass::member)); 1004 } 1005 }; 1006 1007 void printf_positional_arg() { 1008 printf("%1$d", 42); 1009 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1010 // CHECK-FIXES: std::print("{0}", 42); 1011 1012 printf("before %1$d", 42); 1013 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1014 // CHECK-FIXES: std::print("before {0}", 42); 1015 1016 printf("%1$d after", 42); 1017 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1018 // CHECK-FIXES: std::print("{0} after", 42); 1019 1020 printf("before %1$d after", 42); 1021 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1022 // CHECK-FIXES: std::print("before {0} after", 42); 1023 1024 printf("before %2$d between %1$s after", "string", 42); 1025 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1026 // CHECK-FIXES: std::print("before {1} between {0} after", "string", 42); 1027 } 1028 1029 // printf always defaults to right justification,, no matter what the type is of 1030 // the argument. std::format uses left justification by default for strings, and 1031 // right justification for numbers. 1032 void printf_right_justified() { 1033 printf("Right-justified integer %4d after\n", 42); 1034 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1035 // CHECK-FIXES: std::println("Right-justified integer {:4} after", 42); 1036 1037 printf("Right-justified double %4f\n", 227.2); 1038 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1039 // CHECK-FIXES: std::println("Right-justified double {:4f}", 227.2); 1040 1041 printf("Right-justified double %4g\n", 227.4); 1042 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1043 // CHECK-FIXES: std::println("Right-justified double {:4g}", 227.4); 1044 1045 printf("Right-justified integer with field width argument %*d after\n", 5, 424242); 1046 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1047 // CHECK-FIXES: std::println("Right-justified integer with field width argument {:{}} after", 424242, 5); 1048 1049 printf("Right-justified integer with field width argument %2$*1$d after\n", 5, 424242); 1050 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1051 // CHECK-FIXES: std::println("Right-justified integer with field width argument {1:{0}} after", 5, 424242); 1052 1053 printf("Right-justified string %20s\n", "Hello"); 1054 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1055 // CHECK-FIXES: std::println("Right-justified string {:>20}", "Hello"); 1056 1057 printf("Right-justified string with field width argument %2$*1$s after\n", 20, "wibble"); 1058 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1059 // CHECK-FIXES: std::println("Right-justified string with field width argument {1:>{0}} after", 20, "wibble"); 1060 } 1061 1062 // printf always requires - for left justification, no matter what the type is 1063 // of the argument. std::format uses left justification by default for strings, 1064 // and right justification for numbers. 1065 void printf_left_justified() { 1066 printf("Left-justified integer %-4d\n", 42); 1067 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1068 // CHECK-FIXES: std::println("Left-justified integer {:<4}", 42); 1069 1070 printf("Left-justified integer %--4d\n", 42); 1071 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1072 // CHECK-FIXES: std::println("Left-justified integer {:<4}", 42); 1073 1074 printf("Left-justified double %-4f\n", 227.2); 1075 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1076 // CHECK-FIXES: std::println("Left-justified double {:<4f}", 227.2); 1077 1078 printf("Left-justified double %-4g\n", 227.4); 1079 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1080 // CHECK-FIXES: std::println("Left-justified double {:<4g}", 227.4); 1081 1082 printf("Left-justified integer with field width argument %-*d after\n", 5, 424242); 1083 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1084 // CHECK-FIXES: std::println("Left-justified integer with field width argument {:<{}} after", 424242, 5); 1085 1086 printf("Left-justified integer with field width argument %2$-*1$d after\n", 5, 424242); 1087 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1088 // CHECK-FIXES: std::println("Left-justified integer with field width argument {1:<{0}} after", 5, 424242); 1089 1090 printf("Left-justified string %-20s\n", "Hello"); 1091 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1092 // CHECK-FIXES: std::println("Left-justified string {:20}", "Hello"); 1093 1094 printf("Left-justified string with field width argument %2$-*1$s after\n", 5, "wibble"); 1095 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1096 // CHECK-FIXES: std::println("Left-justified string with field width argument {1:{0}} after", 5, "wibble"); 1097 } 1098 1099 void printf_precision() { 1100 printf("Hello %.3f\n", 3.14159); 1101 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1102 // CHECK-FIXES: std::println("Hello {:.3f}", 3.14159); 1103 1104 printf("Hello %10.3f\n", 3.14159); 1105 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1106 // CHECK-FIXES: std::println("Hello {:10.3f}", 3.14159); 1107 1108 printf("Hello %.*f after\n", 10, 3.14159265358979323846); 1109 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1110 // CHECK-FIXES: std::println("Hello {:.{}f} after", 3.14159265358979323846, 10); 1111 1112 printf("Hello %10.*f after\n", 3, 3.14159265358979323846); 1113 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1114 // CHECK-FIXES: std::println("Hello {:10.{}f} after", 3.14159265358979323846, 3); 1115 1116 printf("Hello %*.*f after\n", 10, 4, 3.14159265358979323846); 1117 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1118 // CHECK-FIXES: std::println("Hello {:{}.{}f} after", 3.14159265358979323846, 10, 4); 1119 1120 printf("Hello %1$.*2$f after\n", 3.14159265358979323846, 4); 1121 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1122 // CHECK-FIXES: std::println("Hello {0:.{1}f} after", 3.14159265358979323846, 4); 1123 1124 // Precision is ignored, but maintained on non-numeric arguments 1125 printf("Hello %.5s\n", "Goodbye"); 1126 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1127 // CHECK-FIXES: std::println("Hello {:.5}", "Goodbye"); 1128 1129 printf("Hello %.5c\n", 'G'); 1130 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1131 // CHECK-FIXES: std::println("Hello {:.5}", 'G'); 1132 } 1133 1134 void printf_field_width_and_precision(const std::string &s1, const std::string &s2, const std::string &s3) 1135 { 1136 printf("width only:%*d width and precision:%*.*f precision only:%.*f\n", 3, 42, 4, 2, 3.14159265358979323846, 5, 2.718); 1137 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1138 // CHECK-FIXES: std::println("width only:{:{}} width and precision:{:{}.{}f} precision only:{:.{}f}", 42, 3, 3.14159265358979323846, 4, 2, 2.718, 5); 1139 1140 const unsigned int ui1 = 42, ui2 = 43, ui3 = 44; 1141 printf("casts width only:%*d width and precision:%*.*d precision only:%.*d\n", 3, ui1, 4, 2, ui2, 5, ui3); 1142 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1143 // CHECK-FIXES-NOTSTRICT: std::println("casts width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", ui1, 3, ui2, 4, 2, ui3, 5); 1144 // CHECK-FIXES-STRICT: std::println("casts width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", static_cast<int>(ui1), 3, static_cast<int>(ui2), 4, 2, static_cast<int>(ui3), 5); 1145 1146 printf("c_str removal width only:%*s width and precision:%*.*s precision only:%.*s\n", 3, s1.c_str(), 4, 2, s2.c_str(), 5, s3.c_str()); 1147 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1148 // CHECK-FIXES: std::println("c_str removal width only:{:>{}} width and precision:{:>{}.{}} precision only:{:.{}}", s1, 3, s2, 4, 2, s3, 5); 1149 1150 const std::string *ps1 = &s1, *ps2 = &s2, *ps3 = &s3; 1151 printf("c_str() removal pointer width only:%-*s width and precision:%-*.*s precision only:%-.*s\n", 3, ps1->c_str(), 4, 2, ps2->c_str(), 5, ps3->c_str()); 1152 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1153 // CHECK-FIXES: std::println("c_str() removal pointer width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", *ps1, 3, *ps2, 4, 2, *ps3, 5); 1154 1155 iterator<std::string> is1, is2, is3; 1156 printf("c_str() removal iterator width only:%-*s width and precision:%-*.*s precision only:%-.*s\n", 3, is1->c_str(), 4, 2, is2->c_str(), 5, is3->c_str()); 1157 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1158 // CHECK-FIXES: std::println("c_str() removal iterator width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", *is1, 3, *is2, 4, 2, *is3, 5); 1159 1160 printf("width and precision positional:%1$*2$.*3$f after\n", 3.14159265358979323846, 4, 2); 1161 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1162 // CHECK-FIXES: std::println("width and precision positional:{0:{1}.{2}f} after", 3.14159265358979323846, 4, 2); 1163 1164 const int width = 10, precision = 3; 1165 printf("width only:%3$*1$d width and precision:%4$*1$.*2$f precision only:%5$.*2$f\n", width, precision, 42, 3.1415926, 2.718); 1166 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1167 // CHECK-FIXES: std::println("width only:{2:{0}} width and precision:{3:{0}.{1}f} precision only:{4:.{1}f}", width, precision, 42, 3.1415926, 2.718); 1168 1169 printf("c_str removal width only:%3$*1$s width and precision:%4$*1$.*2$s precision only:%5$.*2$s\n", width, precision, s1.c_str(), s2.c_str(), s3.c_str()); 1170 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1171 // CHECK-FIXES: std::println("c_str removal width only:{2:>{0}} width and precision:{3:>{0}.{1}} precision only:{4:.{1}}", width, precision, s1, s2, s3); 1172 } 1173 1174 void fprintf_field_width_and_precision(const std::string &s1, const std::string &s2, const std::string &s3) { 1175 fprintf(stderr, "width only:%*d width and precision:%*.*f precision only:%.*f\n", 3, 42, 4, 2, 3.14159265358979323846, 5, 2.718); 1176 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 1177 // CHECK-FIXES: std::println(stderr, "width only:{:{}} width and precision:{:{}.{}f} precision only:{:.{}f}", 42, 3, 3.14159265358979323846, 4, 2, 2.718, 5); 1178 1179 fprintf(stderr, "width and precision positional:%1$*2$.*3$f after\n", 3.14159265358979323846, 4, 2); 1180 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 1181 // CHECK-FIXES: std::println(stderr, "width and precision positional:{0:{1}.{2}f} after", 3.14159265358979323846, 4, 2); 1182 1183 fprintf(stderr, "c_str removal width only:%*s width and precision:%*.*s precision only:%.*s\n", 3, s1.c_str(), 4, 2, s2.c_str(), 5, s3.c_str()); 1184 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 1185 // CHECK-FIXES: std::println(stderr, "c_str removal width only:{:>{}} width and precision:{:>{}.{}} precision only:{:.{}}", s1, 3, s2, 4, 2, s3, 5); 1186 1187 const std::string *ps1 = &s1, *ps2 = &s2, *ps3 = &s3; 1188 fprintf(stderr, "c_str() removal pointer width only:%-*s width and precision:%-*.*s precision only:%-.*s\n", 3, ps1->c_str(), 4, 2, ps2->c_str(), 5, ps3->c_str()); 1189 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 1190 // CHECK-FIXES: std::println(stderr, "c_str() removal pointer width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", *ps1, 3, *ps2, 4, 2, *ps3, 5); 1191 1192 iterator<std::string> is1, is2, is3; 1193 fprintf(stderr, "c_str() removal iterator width only:%-*s width and precision:%-*.*s precision only:%-.*s\n", 3, is1->c_str(), 4, 2, is2->c_str(), 5, is3->c_str()); 1194 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 1195 // CHECK-FIXES: std::println(stderr, "c_str() removal iterator width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", *is1, 3, *is2, 4, 2, *is3, 5); 1196 1197 const int width = 10, precision = 3; 1198 fprintf(stderr, "width only:%3$*1$d width and precision:%4$*1$.*2$f precision only:%5$.*2$f\n", width, precision, 42, 3.1415926, 2.718); 1199 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 1200 // CHECK-FIXES: std::println(stderr, "width only:{2:{0}} width and precision:{3:{0}.{1}f} precision only:{4:.{1}f}", width, precision, 42, 3.1415926, 2.718); 1201 1202 fprintf(stderr, "c_str removal width only:%3$*1$s width and precision:%4$*1$.*2$s precision only:%5$.*2$s\n", width, precision, s1.c_str(), s2.c_str(), s3.c_str()); 1203 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 1204 // CHECK-FIXES: std::println(stderr, "c_str removal width only:{2:>{0}} width and precision:{3:>{0}.{1}} precision only:{4:.{1}}", width, precision, s1, s2, s3); 1205 } 1206 1207 void printf_alternative_form() { 1208 printf("Wibble %#x\n", 42); 1209 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1210 // CHECK-FIXES: std::println("Wibble {:#x}", 42); 1211 1212 printf("Wibble %#20x\n", 42); 1213 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1214 // CHECK-FIXES: std::println("Wibble {:#20x}", 42); 1215 1216 printf("Wibble %#020x\n", 42); 1217 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1218 // CHECK-FIXES: std::println("Wibble {:#020x}", 42); 1219 1220 printf("Wibble %#-20x\n", 42); 1221 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1222 // CHECK-FIXES: std::println("Wibble {:<#20x}", 42); 1223 } 1224 1225 void printf_leading_plus() { 1226 printf("Positive integer %+d\n", 42); 1227 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1228 // CHECK-FIXES: std::println("Positive integer {:+}", 42); 1229 1230 printf("Positive double %+f\n", 42.2); 1231 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1232 // CHECK-FIXES: std::println("Positive double {:+f}", 42.2); 1233 1234 printf("Positive double %+g\n", 42.2); 1235 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1236 // CHECK-FIXES: std::println("Positive double {:+g}", 42.2); 1237 1238 // Ignore leading plus on strings to avoid potential runtime exception where 1239 // printf would have just ignored it. 1240 printf("Positive string %+s\n", "string"); 1241 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1242 // CHECK-FIXES: std::println("Positive string {}", "string"); 1243 } 1244 1245 void printf_leading_space() { 1246 printf("Spaced integer % d\n", 42); 1247 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1248 // CHECK-FIXES: std::println("Spaced integer {: }", 42); 1249 1250 printf("Spaced integer %- d\n", 42); 1251 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1252 // CHECK-FIXES: std::println("Spaced integer {: }", 42); 1253 1254 printf("Spaced double % f\n", 42.2); 1255 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1256 // CHECK-FIXES: std::println("Spaced double {: f}", 42.2); 1257 1258 printf("Spaced double % g\n", 42.2); 1259 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1260 // CHECK-FIXES: std::println("Spaced double {: g}", 42.2); 1261 } 1262 1263 void printf_leading_zero() { 1264 printf("Leading zero integer %03d\n", 42); 1265 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1266 // CHECK-FIXES: std::println("Leading zero integer {:03}", 42); 1267 1268 printf("Leading minus and zero integer %-03d minus ignored\n", 42); 1269 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1270 // CHECK-FIXES: std::println("Leading minus and zero integer {:<03} minus ignored", 42); 1271 1272 printf("Leading zero unsigned integer %03u\n", 42U); 1273 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1274 // CHECK-FIXES: std::println("Leading zero unsigned integer {:03}", 42U); 1275 1276 printf("Leading zero double %03f\n", 42.2); 1277 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1278 // CHECK-FIXES: std::println("Leading zero double {:03f}", 42.2); 1279 1280 printf("Leading zero double %03g\n", 42.2); 1281 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1282 // CHECK-FIXES: std::println("Leading zero double {:03g}", 42.2); 1283 } 1284 1285 void printf_leading_plus_and_space() { 1286 // printf prefers plus to space. {fmt} will throw if both are present. 1287 printf("Spaced integer % +d\n", 42); 1288 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1289 // CHECK-FIXES: std::println("Spaced integer {:+}", 42); 1290 1291 printf("Spaced double %+ f\n", 42.2); 1292 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1293 // CHECK-FIXES: std::println("Spaced double {:+f}", 42.2); 1294 1295 printf("Spaced double % +g\n", 42.2); 1296 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1297 // CHECK-FIXES: std::println("Spaced double {:+g}", 42.2); 1298 } 1299 1300 void printf_leading_zero_and_plus() { 1301 printf("Leading zero integer %+03d\n", 42); 1302 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1303 // CHECK-FIXES: std::println("Leading zero integer {:+03}", 42); 1304 1305 printf("Leading zero double %0+3f\n", 42.2); 1306 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1307 // CHECK-FIXES: std::println("Leading zero double {:+03f}", 42.2); 1308 1309 printf("Leading zero double %0+3g\n", 42.2); 1310 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1311 // CHECK-FIXES: std::println("Leading zero double {:+03g}", 42.2); 1312 } 1313 1314 void printf_leading_zero_and_space() { 1315 printf("Leading zero and space integer %0 3d\n", 42); 1316 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1317 // CHECK-FIXES: std::println("Leading zero and space integer {: 03}", 42); 1318 1319 printf("Leading zero and space double %0 3f\n", 42.2); 1320 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1321 // CHECK-FIXES: std::println("Leading zero and space double {: 03f}", 42.2); 1322 1323 printf("Leading zero and space double %0 3g\n", 42.2); 1324 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1325 // CHECK-FIXES: std::println("Leading zero and space double {: 03g}", 42.2); 1326 } 1327 1328 // add signed plained enum too 1329 enum PlainEnum { red }; 1330 enum SignedPlainEnum { black = -42 }; 1331 enum BoolEnum : unsigned int { yellow }; 1332 enum CharEnum : char { purple }; 1333 enum SCharEnum : signed char { aquamarine }; 1334 enum UCharEnum : unsigned char { pink }; 1335 enum ShortEnum : short { beige }; 1336 enum UShortEnum : unsigned short { grey }; 1337 enum IntEnum : int { green }; 1338 enum UIntEnum : unsigned int { blue }; 1339 enum LongEnum : long { magenta }; 1340 enum ULongEnum : unsigned long { cyan }; 1341 enum LongLongEnum : long long { taupe }; 1342 enum ULongLongEnum : unsigned long long { brown }; 1343 1344 void printf_enum_d() { 1345 PlainEnum plain_enum; 1346 printf("%d", plain_enum); 1347 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1348 // CHECK-FIXES: std::print("{}", static_cast<int>(plain_enum)); 1349 1350 SignedPlainEnum splain_enum; 1351 printf("%d", splain_enum); 1352 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1353 // CHECK-FIXES: std::print("{}", static_cast<int>(splain_enum)); 1354 1355 BoolEnum bool_enum; 1356 printf("%d", bool_enum); 1357 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1358 // CHECK-FIXES: std::print("{}", static_cast<int>(bool_enum)); 1359 1360 CharEnum char_enum; 1361 printf("%d", char_enum); 1362 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1363 // CHECK-FIXES: std::print("{}", static_cast<signed char>(char_enum)); 1364 1365 SCharEnum schar_enum; 1366 printf("%d", schar_enum); 1367 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1368 // CHECK-FIXES: std::print("{}", static_cast<signed char>(schar_enum)); 1369 1370 UCharEnum uchar_enum; 1371 printf("%d", uchar_enum); 1372 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1373 // CHECK-FIXES: std::print("{}", static_cast<signed char>(uchar_enum)); 1374 1375 ShortEnum short_enum; 1376 printf("%d", short_enum); 1377 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1378 // CHECK-FIXES: std::print("{}", static_cast<short>(short_enum)); 1379 1380 UShortEnum ushort_enum; 1381 printf("%d", ushort_enum); 1382 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1383 // CHECK-FIXES: std::print("{}", static_cast<short>(ushort_enum)); 1384 1385 IntEnum int_enum; 1386 printf("%d", int_enum); 1387 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1388 // CHECK-FIXES: std::print("{}", static_cast<int>(int_enum)); 1389 1390 UIntEnum uint_enum; 1391 printf("%d", uint_enum); 1392 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1393 // CHECK-FIXES: std::print("{}", static_cast<int>(uint_enum)); 1394 1395 LongEnum long_enum; 1396 printf("%d", long_enum); 1397 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1398 // CHECK-FIXES: std::print("{}", static_cast<long>(long_enum)); 1399 1400 ULongEnum ulong_enum; 1401 printf("%d", ulong_enum); 1402 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1403 // CHECK-FIXES: std::print("{}", static_cast<long>(ulong_enum)); 1404 1405 LongLongEnum longlong_enum; 1406 printf("%d", longlong_enum); 1407 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1408 // CHECK-FIXES: std::print("{}", static_cast<long long>(longlong_enum)); 1409 1410 ULongLongEnum ulonglong_enum; 1411 printf("%d", ulonglong_enum); 1412 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1413 // CHECK-FIXES: std::print("{}", static_cast<long long>(ulonglong_enum)); 1414 } 1415 1416 void printf_enum_u() { 1417 PlainEnum plain_enum; 1418 printf("%u", plain_enum); 1419 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1420 // CHECK-FIXES: std::print("{}", static_cast<unsigned int>(plain_enum)); 1421 1422 SignedPlainEnum splain_enum; 1423 printf("%u", splain_enum); 1424 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1425 // CHECK-FIXES: std::print("{}", static_cast<unsigned int>(splain_enum)); 1426 1427 BoolEnum bool_enum; 1428 printf("%u", bool_enum); 1429 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1430 // CHECK-FIXES: std::print("{}", static_cast<unsigned int>(bool_enum)); 1431 1432 CharEnum char_enum; 1433 printf("%u", char_enum); 1434 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1435 // CHECK-FIXES: std::print("{}", static_cast<unsigned char>(char_enum)); 1436 1437 SCharEnum schar_enum; 1438 printf("%u", schar_enum); 1439 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1440 // CHECK-FIXES: std::print("{}", static_cast<unsigned char>(schar_enum)); 1441 1442 UCharEnum uchar_enum; 1443 printf("%u", uchar_enum); 1444 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1445 // CHECK-FIXES: std::print("{}", static_cast<unsigned char>(uchar_enum)); 1446 1447 ShortEnum short_enum; 1448 printf("%u", short_enum); 1449 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1450 // CHECK-FIXES: std::print("{}", static_cast<unsigned short>(short_enum)); 1451 1452 UShortEnum ushort_enum; 1453 printf("%u", ushort_enum); 1454 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1455 // CHECK-FIXES: std::print("{}", static_cast<unsigned short>(ushort_enum)); 1456 1457 IntEnum int_enum; 1458 printf("%u", int_enum); 1459 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1460 // CHECK-FIXES: std::print("{}", static_cast<unsigned int>(int_enum)); 1461 1462 UIntEnum uint_enum; 1463 printf("%u", uint_enum); 1464 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1465 // CHECK-FIXES: std::print("{}", static_cast<unsigned int>(uint_enum)); 1466 1467 LongEnum long_enum; 1468 printf("%u", long_enum); 1469 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1470 // CHECK-FIXES: std::print("{}", static_cast<unsigned long>(long_enum)); 1471 1472 ULongEnum ulong_enum; 1473 printf("%u", ulong_enum); 1474 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1475 // CHECK-FIXES: std::print("{}", static_cast<unsigned long>(ulong_enum)); 1476 1477 LongLongEnum longlong_enum; 1478 printf("%u", longlong_enum); 1479 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1480 // CHECK-FIXES: std::print("{}", static_cast<unsigned long long>(longlong_enum)); 1481 1482 ULongLongEnum ulonglong_enum; 1483 printf("%u", ulonglong_enum); 1484 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1485 // CHECK-FIXES: std::print("{}", static_cast<unsigned long long>(ulonglong_enum)); 1486 } 1487 1488 void printf_string_function(const char *(*callback)()) { 1489 printf("printf string from callback %s", callback()); 1490 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1491 // CHECK-FIXES: std::print("printf string from callback {}", callback()); 1492 } 1493 1494 template <typename CharType> 1495 struct X 1496 { 1497 const CharType *str() const; 1498 }; 1499 1500 void printf_string_member_function(const X<char> &x, const X<const char> &cx) { 1501 printf("printf string from member function %s", x.str()); 1502 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1503 // CHECK-FIXES: std::print("printf string from member function {}", x.str()); 1504 1505 printf("printf string from member function on const %s", cx.str()); 1506 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1507 // CHECK-FIXES: std::print("printf string from member function on const {}", cx.str()); 1508 } 1509 1510 void printf_string_cstr(const std::string &s1, const std::string &s2) { 1511 printf("printf string one c_str %s", s1.c_str()); 1512 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1513 // CHECK-FIXES: std::print("printf string one c_str {}", s1); 1514 1515 printf("printf string two c_str %s %s\n", s1.c_str(), s2.data()); 1516 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1517 // CHECK-FIXES: std::println("printf string two c_str {} {}", s1, s2); 1518 } 1519 1520 void printf_not_char_string_cstr(const std::wstring &ws1) { 1521 // This test is to check that we only remove 1522 // std::basic_string<CharType>::c_str()/data() when CharType is char. I've 1523 // been unable to come up with a genuine situation where someone would have 1524 // actually successfully called those methods when this isn't the case without 1525 // -Wformat warning, but it seems sensible to restrict removal regardless. 1526 printf("printf bogus wstring c_str %s", ws1.c_str()); 1527 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1528 // CHECK-FIXES: std::print("printf bogus wstring c_str {}", ws1.c_str()); 1529 } 1530 1531 void fprintf_string_cstr(const std::string &s1) { 1532 fprintf(stderr, "fprintf string c_str %s", s1.c_str()); 1533 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'fprintf' [modernize-use-std-print] 1534 // CHECK-FIXES: std::print(stderr, "fprintf string c_str {}", s1); 1535 } 1536 1537 void printf_string_pointer_cstr(const std::string *s1, const std::string *s2) { 1538 printf("printf string pointer one c_str %s", s1->c_str()); 1539 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1540 // CHECK-FIXES: std::print("printf string pointer one c_str {}", *s1); 1541 1542 printf("printf string pointer two c_str %s %s\n", s1->c_str(), s2->data()); 1543 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1544 // CHECK-FIXES: std::println("printf string pointer two c_str {} {}", *s1, *s2); 1545 } 1546 1547 void fprintf_string_pointer_cstr(const std::string *s1) { 1548 fprintf(stderr, "fprintf string pointer c_str %s", s1->c_str()); 1549 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'fprintf' [modernize-use-std-print] 1550 // CHECK-FIXES: std::print(stderr, "fprintf string pointer c_str {}", *s1); 1551 } 1552 1553 void printf_iterator_cstr(iterator<std::string> i1, iterator<std::string> i2) 1554 { 1555 printf("printf iterator c_str %s %s\n", i1->c_str(), i2->data()); 1556 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1557 // CHECK-FIXES: std::println("printf iterator c_str {} {}", *i1, *i2); 1558 } 1559 1560 // Something that isn't std::string, so the calls to c_str() and data() must not 1561 // be removed even though the printf call will be replaced. 1562 struct S 1563 { 1564 const char *c_str() const; 1565 const char *data() const; 1566 }; 1567 1568 void p(S s1, S *s2) 1569 { 1570 printf("Not std::string %s %s", s1.c_str(), s2->c_str()); 1571 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1572 // CHECK-FIXES: std::print("Not std::string {} {}", s1.c_str(), s2->c_str()); 1573 1574 printf("Not std::string %s %s", s1.data(), s2->data()); 1575 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1576 // CHECK-FIXES: std::print("Not std::string {} {}", s1.data(), s2->data()); 1577 } 1578 1579 // These need PRI and __PRI prefixes so that the check gets as far as looking 1580 // for where the macro comes from. 1581 #define PRI_FMT_MACRO "s" 1582 #define __PRI_FMT_MACRO "s" 1583 1584 void macro_expansion(const char *s) 1585 { 1586 const uint64_t u64 = 42; 1587 const uint32_t u32 = 32; 1588 1589 printf("Replaceable macro at end %" PRIu64, u64); 1590 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1591 // CHECK-FIXES: std::print("Replaceable macro at end {}", u64); 1592 1593 printf("Replaceable macros in middle %" PRIu64 " %" PRIu32 "\n", u64, u32); 1594 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1595 // CHECK-FIXES: std::println("Replaceable macros in middle {} {}", u64, u32); 1596 1597 printf("Unreplaceable macro at end %" PRI_FMT_MACRO, s); 1598 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unable to use 'std::print' instead of 'printf' because format string contains unreplaceable macro 'PRI_FMT_MACRO' [modernize-use-std-print] 1599 1600 printf(PRI_FMT_MACRO " Unreplaceable macro at beginning %s", s); 1601 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unable to use 'std::print' instead of 'printf' because format string contains unreplaceable macro 'PRI_FMT_MACRO' [modernize-use-std-print] 1602 1603 printf("Unreplacemable macro %" __PRI_FMT_MACRO " in the middle", s); 1604 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unable to use 'std::print' instead of 'printf' because format string contains unreplaceable macro '__PRI_FMT_MACRO' [modernize-use-std-print] 1605 1606 printf("First macro is replaceable %" PRIu64 " but second one is not %" PRI_FMT_MACRO, u64, s); 1607 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unable to use 'std::print' instead of 'printf' because format string contains unreplaceable macro 'PRI_FMT_MACRO' [modernize-use-std-print] 1608 1609 // Needs a PRI prefix so that we get as far as looking for where the macro comes from 1610 printf(" macro from command line %" PRI_CMDLINE_MACRO, s); 1611 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unable to use 'std::print' instead of 'printf' because format string contains unreplaceable macro 'PRI_CMDLINE_MACRO' [modernize-use-std-print] 1612 1613 // Needs a __PRI prefix so that we get as far as looking for where the macro comes from 1614 printf(" macro from command line %" __PRI_CMDLINE_MACRO, s); 1615 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unable to use 'std::print' instead of 'printf' because format string contains unreplaceable macro '__PRI_CMDLINE_MACRO' [modernize-use-std-print] 1616 1617 // We ought to be able to fix this since the macro surrounds the whole call 1618 // and therefore can't change the format string independently. This is 1619 // required to be able to fix calls inside Catch2 macros for example. 1620 #define SURROUND_ALL(x) x 1621 SURROUND_ALL(printf("Macro surrounding entire invocation %" PRIu64, u64)); 1622 // CHECK-MESSAGES: [[@LINE-1]]:16: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1623 // CHECK-FIXES: SURROUND_ALL(std::print("Macro surrounding entire invocation {}", u64)); 1624 1625 // But having that surrounding macro shouldn't stop us ignoring an 1626 // unreplaceable macro elsewhere. 1627 SURROUND_ALL(printf("Macro surrounding entire invocation with unreplaceable macro %" PRI_FMT_MACRO, s)); 1628 // CHECK-MESSAGES: [[@LINE-1]]:16: warning: unable to use 'std::print' instead of 'printf' because format string contains unreplaceable macro 'PRI_FMT_MACRO' [modernize-use-std-print] 1629 1630 // At the moment at least the check will replace occurrences where the 1631 // function name is the result of expanding a macro. 1632 #define SURROUND_FUNCTION_NAME(x) x 1633 SURROUND_FUNCTION_NAME(printf)("Hello %d", 4442); 1634 // CHECK-MESSAGES: [[@LINE-1]]:26: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1635 // CHECK-FIXES: std::print("Hello {}", 4442); 1636 1637 // We can't safely fix occurrences where the macro may affect the format 1638 // string differently in different builds. 1639 #define SURROUND_FORMAT(x) "!" x 1640 printf(SURROUND_FORMAT("Hello %d"), 4443); 1641 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unable to use 'std::print' instead of 'printf' because format string contains unreplaceable macro 'SURROUND_FORMAT' [modernize-use-std-print] 1642 } 1643