1 // RUN: %check_clang_tidy -check-suffixes=,STRICT \ 2 // RUN: -std=c++23 %s modernize-use-std-print %t -- \ 3 // RUN: -config="{CheckOptions: [{key: StrictMode, value: true}]}" \ 4 // RUN: -- -isystem %clang_tidy_headers 5 // RUN: %check_clang_tidy -check-suffixes=,NOTSTRICT \ 6 // RUN: -std=c++23 %s modernize-use-std-print %t -- \ 7 // RUN: -config="{CheckOptions: [{key: StrictMode, value: false}]}" \ 8 // RUN: -- -isystem %clang_tidy_headers 9 #include <cstddef> 10 #include <cstdint> 11 #include <cstdio> 12 // CHECK-FIXES: #include <print> 13 #include <inttypes.h> 14 #include <string.h> 15 #include <string> 16 17 void printf_simple() { 18 printf("Hello"); 19 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 20 // CHECK-FIXES: std::print("Hello"); 21 } 22 23 void printf_newline() { 24 printf("Hello\n"); 25 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 26 // CHECK-FIXES: std::println("Hello"); 27 28 printf("Split" "\n"); 29 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 30 // CHECK-FIXES: std::println("Split"); 31 32 printf("Double\n\n"); 33 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 34 // CHECK-FIXES: std::println("Double\n"); 35 } 36 37 void printf_deceptive_newline() { 38 printf("Hello\\n"); 39 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 40 // CHECK-FIXES: std::print("Hello\\n"); 41 42 printf("Hello\x0a"); 43 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 44 // CHECK-FIXES: std::println("Hello"); 45 } 46 47 void fprintf_simple() { 48 fprintf(stderr, "Hello"); 49 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'fprintf' [modernize-use-std-print] 50 // CHECK-FIXES: std::print(stderr, "Hello"); 51 } 52 53 void std_printf_simple() { 54 std::printf("std::Hello"); 55 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 56 // CHECK-FIXES: std::print("std::Hello"); 57 } 58 59 void printf_escape() { 60 printf("before \t"); 61 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 62 // CHECK-FIXES: std::print("before \t"); 63 64 printf("\n after"); 65 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 66 // CHECK-FIXES: std::print("\n after"); 67 68 printf("before \a after"); 69 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 70 // CHECK-FIXES: std::print("before \a after"); 71 72 printf("Bell\a%dBackspace\bFF%s\fNewline\nCR\rTab\tVT\vEscape\x1b\x07%d", 42, "string", 99); 73 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 74 // CHECK-FIXES: std::print("Bell\a{}Backspace\bFF{}\fNewline\nCR\rTab\tVT\vEscape\x1b\a{}", 42, "string", 99); 75 76 printf("not special \x1b\x01\x7f"); 77 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 78 // CHECK-FIXES: std::print("not special \x1b\x01\x7f"); 79 } 80 81 void printf_percent() { 82 printf("before %%"); 83 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 84 // CHECK-FIXES: std::print("before %"); 85 86 printf("%% after"); 87 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 88 // CHECK-FIXES: std::print("% after"); 89 90 printf("before %% after"); 91 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 92 // CHECK-FIXES: std::print("before % after"); 93 94 printf("Hello %% and another %%"); 95 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 96 // CHECK-FIXES: std::print("Hello % and another %"); 97 98 printf("Not a string %%s"); 99 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 100 // CHECK-FIXES: std::print("Not a string %s"); 101 } 102 103 void printf_curlies() { 104 printf("%d {}", 42); 105 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 106 // CHECK-FIXES: std::print("{} {{[{][{]}}}}", 42); 107 108 printf("{}"); 109 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 110 // CHECK-FIXES: std::print("{{[{][{]}}}}"); 111 } 112 113 void printf_unsupported_format_specifiers() { 114 int pos; 115 printf("%d %n %d\n", 42, &pos, 72); 116 // 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] 117 118 printf("Error %m\n"); 119 // 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] 120 } 121 122 void printf_not_string_literal(const char *fmt) { 123 // We can't convert the format string if it's not a literal 124 printf(fmt, 42); 125 } 126 127 void printf_inttypes_ugliness() { 128 // The one advantage of the checker seeing the token pasted version of the 129 // format string is that we automatically cope with the horrendously-ugly 130 // inttypes.h macros! 131 int64_t u64 = 42; 132 uintmax_t umax = 4242; 133 printf("uint64:%" PRId64 " uintmax:%" PRIuMAX "\n", u64, umax); 134 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 135 // CHECK-FIXES: std::println("uint64:{} uintmax:{}", u64, umax); 136 } 137 138 void printf_raw_string() { 139 // This one doesn't require the format string to be changed, so it stays intact 140 printf(R"(First\Second)"); 141 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 142 // CHECK-FIXES: std::print(R"(First\Second)"); 143 144 // This one does require the format string to be changed, so unfortunately it 145 // gets reformatted as a normal string. 146 printf(R"(First %d\Second)", 42); 147 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 148 // CHECK-FIXES: std::print("First {}\\Second", 42); 149 } 150 151 void printf_integer_d() { 152 const bool b = true; 153 // The "d" type is necessary here for compatibility with printf since 154 // std::print will print booleans as "true" or "false". 155 printf("Integer %d from bool\n", b); 156 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 157 // CHECK-FIXES: std::println("Integer {:d} from bool", b); 158 159 // The "d" type is necessary here for compatibility with printf since 160 // std::print will print booleans as "true" or "false". 161 printf("Integer %i from bool\n", b); 162 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 163 // CHECK-FIXES: std::println("Integer {:d} from bool", b); 164 165 // The 'd' is always necessary since otherwise the parameter will be formatted as a character 166 const char c = 'A'; 167 printf("Integer %d from char\n", c); 168 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 169 // CHECK-FIXES: std::println("Integer {:d} from char", c); 170 171 printf("Integer %i from char\n", 'A'); 172 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 173 // CHECK-FIXES: std::println("Integer {:d} from char", 'A'); 174 175 const signed char sc = 'A'; 176 printf("Integer %hhd from signed char\n", sc); 177 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 178 // CHECK-FIXES: std::println("Integer {} from signed char", sc); 179 180 printf("Integer %hhi from signed char\n", sc); 181 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 182 // CHECK-FIXES: std::println("Integer {} from signed char", sc); 183 184 const unsigned char uc = 'A'; 185 printf("Integer %hhd from unsigned char\n", uc); 186 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 187 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned char", uc); 188 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned char", static_cast<signed char>(uc)); 189 190 printf("Integer %hhi from unsigned char\n", uc); 191 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 192 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned char", uc); 193 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned char", static_cast<signed char>(uc)); 194 195 const int8_t i8 = 42; 196 printf("Integer %" PRIi8 " from int8_t\n", i8); 197 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 198 // CHECK-FIXES: std::println("Integer {} from int8_t", i8); 199 200 const int_fast8_t if8 = 42; 201 printf("Integer %" PRIiFAST8 " from int_fast8_t\n", if8); 202 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 203 // CHECK-FIXES: std::println("Integer {} from int_fast8_t", if8); 204 205 const int_least8_t il8 = 42; 206 printf("Integer %" PRIiFAST8 " from int_least8_t\n", il8); 207 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 208 // CHECK-FIXES: std::println("Integer {} from int_least8_t", il8); 209 210 const uint8_t u8 = 42U; 211 const std::uint8_t su8 = u8; 212 printf("Integers %" PRIi8 " and %" PRId8 " from uint8_t\n", u8, su8); 213 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 214 // CHECK-FIXES-NOTSTRICT: std::println("Integers {} and {} from uint8_t", u8, su8); 215 // CHECK-FIXES-STRICT: std::println("Integers {} and {} from uint8_t", static_cast<int8_t>(u8), static_cast<std::int8_t>(su8)); 216 217 const uint_fast8_t uf8 = 42U; 218 printf("Integer %" PRIiFAST8 " from uint_fast8_t\n", uf8); 219 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 220 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from uint_fast8_t", uf8); 221 // CHECK-FIXES-STRICT: std::println("Integer {} from uint_fast8_t", static_cast<int_fast8_t>(uf8)); 222 223 const uint_least8_t ul8 = 42U; 224 printf("Integer %" PRIiLEAST8 " from uint_least8_t\n", ul8); 225 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 226 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from uint_least8_t", ul8); 227 // CHECK-FIXES-STRICT: std::println("Integer {} from uint_least8_t", static_cast<int_least8_t>(ul8)); 228 229 const short s = 42; 230 printf("Integer %hd from short\n", s); 231 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 232 // CHECK-FIXES: std::println("Integer {} from short", s); 233 234 printf("Integer %hi from short\n", s); 235 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 236 // CHECK-FIXES: std::println("Integer {} from short", s); 237 238 const unsigned short us = 42U; 239 printf("Integer %hd from unsigned short\n", us); 240 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 241 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned short", us); 242 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned short", static_cast<short>(us)); 243 244 printf("Integer %hi from unsigned short\n", us); 245 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 246 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned short", us); 247 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned short", static_cast<short>(us)); 248 249 const int i = 42; 250 printf("Integer %d from integer\n", i); 251 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 252 // CHECK-FIXES: std::println("Integer {} from integer", i); 253 254 printf("Integer %i from integer\n", i); 255 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 256 // CHECK-FIXES: std::println("Integer {} from integer", i); 257 258 const unsigned int ui = 42U; 259 printf("Integer %d from unsigned integer\n", ui); 260 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 261 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned integer", ui); 262 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned integer", static_cast<int>(ui)); 263 264 printf("Integer %i from unsigned integer\n", ui); 265 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 266 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned integer", ui); 267 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned integer", static_cast<int>(ui)); 268 269 const long l = 42L; 270 printf("Integer %ld from long\n", l); 271 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 272 // CHECK-FIXES: std::println("Integer {} from long", l); 273 274 printf("Integer %li from long\n", l); 275 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 276 // CHECK-FIXES: std::println("Integer {} from long", l); 277 278 const unsigned long ul = 42UL; 279 printf("Integer %ld from unsigned long\n", ul); 280 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 281 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned long", ul); 282 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned long", static_cast<long>(ul)); 283 284 printf("Integer %li from unsigned long\n", ul); 285 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 286 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned long", ul); 287 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned long", static_cast<long>(ul)); 288 289 const long long ll = 42LL; 290 printf("Integer %lld from long long\n", ll); 291 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 292 // CHECK-FIXES: std::println("Integer {} from long long", ll); 293 294 printf("Integer %lli from long long\n", ll); 295 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 296 // CHECK-FIXES: std::println("Integer {} from long long", ll); 297 298 const unsigned long long ull = 42ULL; 299 printf("Integer %lld from unsigned long long\n", ull); 300 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 301 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned long long", ull); 302 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned long long", static_cast<long long>(ull)); 303 304 printf("Integer %lli from unsigned long long\n", ull); 305 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 306 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned long long", ull); 307 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned long long", static_cast<long long>(ull)); 308 309 const intmax_t im = 42; 310 const std::intmax_t sim = im; 311 printf("Integers %jd and %jd from intmax_t\n", im, sim); 312 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 313 // CHECK-FIXES: std::println("Integers {} and {} from intmax_t", im, sim); 314 315 printf("Integers %ji and %ji from intmax_t\n", im, sim); 316 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 317 // CHECK-FIXES: std::println("Integers {} and {} from intmax_t", im, sim); 318 319 const uintmax_t uim = 42; 320 const std::uintmax_t suim = uim; 321 printf("Integers %jd and %jd from uintmax_t\n", uim, suim); 322 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 323 // CHECK-FIXES-NOTSTRICT: std::println("Integers {} and {} from uintmax_t", uim, suim); 324 // CHECK-FIXES-STRICT: std::println("Integers {} and {} from uintmax_t", static_cast<intmax_t>(uim), static_cast<std::intmax_t>(suim)); 325 326 printf("Integer %ji from intmax_t\n", uim); 327 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 328 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from intmax_t", uim); 329 // CHECK-FIXES-STRICT: std::println("Integer {} from intmax_t", static_cast<intmax_t>(uim)); 330 331 const int ai[] = { 0, 1, 2, 3}; 332 const ptrdiff_t pd = &ai[3] - &ai[0]; 333 const std::ptrdiff_t spd = pd; 334 printf("Integers %td and %td from ptrdiff_t\n", pd, spd); 335 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 336 // CHECK-FIXES: std::println("Integers {} and {} from ptrdiff_t", pd, spd); 337 338 printf("Integers %ti and %ti from ptrdiff_t\n", pd, spd); 339 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 340 // CHECK-FIXES: std::println("Integers {} and {} from ptrdiff_t", pd, spd); 341 342 const size_t z = 42UL; 343 const std::size_t sz = z; 344 printf("Integers %zd and %zd from size_t\n", z, sz); 345 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 346 // CHECK-FIXES-NOTSTRICT: std::println("Integers {} and {} from size_t", z, sz); 347 // CHECK-FIXES-STRICT: std::println("Integers {} and {} from size_t", static_cast<ssize_t>(z), static_cast<std::ssize_t>(sz)); 348 } 349 350 void printf_integer_u() 351 { 352 const bool b = true; 353 // The "d" type is necessary here for compatibility with printf since 354 // std::print will print booleans as "true" or "false". 355 printf("Unsigned integer %u from bool\n", b); 356 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 357 // CHECK-FIXES: std::println("Unsigned integer {:d} from bool", b); 358 359 const char c = 'A'; 360 printf("Unsigned integer %hhu from char\n", c); 361 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 362 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {:d} from char", c); 363 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from char", static_cast<unsigned char>(c)); 364 365 const signed char sc = 'A'; 366 printf("Unsigned integer %hhu from signed char\n", sc); 367 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 368 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from signed char", sc); 369 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from signed char", static_cast<unsigned char>(sc)); 370 371 printf("Unsigned integer %u from signed char\n", sc); 372 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 373 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from signed char", sc); 374 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from signed char", static_cast<unsigned char>(sc)); 375 376 const unsigned char uc = 'A'; 377 printf("Unsigned integer %hhu from unsigned char\n", uc); 378 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 379 // CHECK-FIXES: std::println("Unsigned integer {} from unsigned char", uc); 380 381 printf("Unsigned integer %u from unsigned char\n", uc); 382 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 383 // CHECK-FIXES: std::println("Unsigned integer {} from unsigned char", uc); 384 385 const int8_t i8 = 42; 386 printf("Unsigned integer %" PRIu8 " from int8_t\n", i8); 387 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 388 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from int8_t", i8); 389 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from int8_t", static_cast<uint8_t>(i8)); 390 391 const int_fast8_t if8 = 42; 392 printf("Unsigned integer %" PRIuFAST8 " from int_fast8_t\n", if8); 393 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 394 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from int_fast8_t", if8); 395 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from int_fast8_t", static_cast<uint_fast8_t>(if8)); 396 397 const int_least8_t il8 = 42; 398 printf("Unsigned integer %" PRIuFAST8 " from int_least8_t\n", il8); 399 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 400 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from int_least8_t", il8); 401 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from int_least8_t", static_cast<uint_least8_t>(il8)); 402 403 const uint8_t u8 = 42U; 404 printf("Unsigned integer %" PRIu8 " from uint8_t\n", u8); 405 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 406 // CHECK-FIXES: std::println("Unsigned integer {} from uint8_t", u8); 407 408 const uint_fast8_t uf8 = 42U; 409 printf("Unsigned integer %" PRIuFAST8 " from uint_fast8_t\n", uf8); 410 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 411 // CHECK-FIXES: std::println("Unsigned integer {} from uint_fast8_t", uf8); 412 413 const uint_least8_t ul8 = 42U; 414 printf("Unsigned integer %" PRIuLEAST8 " from uint_least8_t\n", ul8); 415 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 416 // CHECK-FIXES: std::println("Unsigned integer {} from uint_least8_t", ul8); 417 418 const short s = 42; 419 printf("Unsigned integer %hu from short\n", s); 420 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 421 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from short", s); 422 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from short", static_cast<unsigned short>(s)); 423 424 const unsigned short us = 42U; 425 printf("Unsigned integer %hu from unsigned short\n", us); 426 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 427 // CHECK-FIXES: std::println("Unsigned integer {} from unsigned short", us); 428 429 const int i = 42; 430 printf("Unsigned integer %u from signed integer\n", i); 431 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 432 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from signed integer", i); 433 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from signed integer", static_cast<unsigned int>(i)); 434 435 const unsigned int ui = 42U; 436 printf("Unsigned integer %u from unsigned integer\n", ui); 437 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 438 // CHECK-FIXES: std::println("Unsigned integer {} from unsigned integer", ui); 439 440 const long l = 42L; 441 printf("Unsigned integer %u from signed long\n", l); 442 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 443 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from signed long", l); 444 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from signed long", static_cast<unsigned long>(l)); 445 446 const unsigned long ul = 42UL; 447 printf("Unsigned integer %lu from unsigned long\n", ul); 448 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 449 // CHECK-FIXES: std::println("Unsigned integer {} from unsigned long", ul); 450 451 const long long ll = 42LL; 452 printf("Unsigned integer %llu from long long\n", ll); 453 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 454 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from long long", ll); 455 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from long long", static_cast<unsigned long long>(ll)); 456 457 const unsigned long long ull = 42ULL; 458 printf("Unsigned integer %llu from unsigned long long\n", ull); 459 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 460 // CHECK-FIXES: std::println("Unsigned integer {} from unsigned long long", ull); 461 462 const intmax_t im = 42; 463 const std::intmax_t sim = im; 464 printf("Unsigned integers %ju and %ju from intmax_t\n", im, sim); 465 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 466 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integers {} and {} from intmax_t", im, sim); 467 // CHECK-FIXES-STRICT: std::println("Unsigned integers {} and {} from intmax_t", static_cast<uintmax_t>(im), static_cast<std::uintmax_t>(sim)); 468 469 const uintmax_t uim = 42U; 470 const std::uintmax_t suim = uim; 471 printf("Unsigned integers %ju and %ju from uintmax_t\n", uim, suim); 472 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 473 // CHECK-FIXES: std::println("Unsigned integers {} and {} from uintmax_t", uim, suim); 474 475 const int ai[] = { 0, 1, 2, 3}; 476 const ptrdiff_t pd = &ai[3] - &ai[0]; 477 const std::ptrdiff_t spd = pd; 478 printf("Unsigned integers %tu and %tu from ptrdiff_t\n", pd, spd); 479 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 480 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integers {} and {} from ptrdiff_t", pd, spd); 481 // CHECK-FIXES-STRICT: std::println("Unsigned integers {} and {} from ptrdiff_t", static_cast<size_t>(pd), static_cast<std::size_t>(spd)); 482 483 const size_t z = 42U; 484 const std::size_t sz = z; 485 printf("Unsigned integers %zu and %zu from size_t\n", z, sz); 486 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 487 // CHECK-FIXES: std::println("Unsigned integers {} and {} from size_t", z, sz); 488 } 489 490 // This checks that we get the argument offset right with the extra FILE * argument 491 void fprintf_integer() { 492 fprintf(stderr, "Integer %d from integer\n", 42); 493 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 494 // CHECK-FIXES: std::println(stderr, "Integer {} from integer", 42); 495 496 fprintf(stderr, "Integer %i from integer\n", 65); 497 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 498 // CHECK-FIXES: std::println(stderr, "Integer {} from integer", 65); 499 500 fprintf(stderr, "Integer %i from char\n", 'A'); 501 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 502 // CHECK-FIXES: std::println(stderr, "Integer {:d} from char", 'A'); 503 504 fprintf(stderr, "Integer %d from char\n", 'A'); 505 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 506 // CHECK-FIXES: std::println(stderr, "Integer {:d} from char", 'A'); 507 } 508 509 void printf_char() { 510 const char c = 'A'; 511 printf("Char %c from char\n", c); 512 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 513 // CHECK-FIXES: std::println("Char {} from char", c); 514 515 const signed char sc = 'A'; 516 printf("Char %c from signed char\n", sc); 517 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 518 // CHECK-FIXES: std::println("Char {:c} from signed char", sc); 519 520 const unsigned char uc = 'A'; 521 printf("Char %c from unsigned char\n", uc); 522 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 523 // CHECK-FIXES: std::println("Char {:c} from unsigned char", uc); 524 525 const int i = 65; 526 printf("Char %c from integer\n", i); 527 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 528 // CHECK-FIXES: std::println("Char {:c} from integer", i); 529 530 const unsigned int ui = 65; 531 printf("Char %c from unsigned integer\n", ui); 532 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 533 // CHECK-FIXES: std::println("Char {:c} from unsigned integer", ui); 534 535 const unsigned long long ull = 65; 536 printf("Char %c from unsigned long long\n", ull); 537 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 538 // CHECK-FIXES: std::println("Char {:c} from unsigned long long", ull); 539 } 540 541 void printf_bases() { 542 printf("Hex %lx\n", 42L); 543 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 544 // CHECK-FIXES: std::println("Hex {:x}", 42L); 545 546 printf("HEX %X\n", 42); 547 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 548 // CHECK-FIXES: std::println("HEX {:X}", 42); 549 550 printf("Oct %lo\n", 42L); 551 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 552 // CHECK-FIXES: std::println("Oct {:o}", 42L); 553 } 554 555 void printf_alternative_forms() { 556 printf("Hex %#lx\n", 42L); 557 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 558 // CHECK-FIXES: std::println("Hex {:#x}", 42L); 559 560 printf("HEX %#X\n", 42); 561 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 562 // CHECK-FIXES: std::println("HEX {:#X}", 42); 563 564 printf("Oct %#lo\n", 42L); 565 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 566 // CHECK-FIXES: std::println("Oct {:#o}", 42L); 567 568 printf("Double %#f %#F\n", -42.0, -42.0); 569 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 570 // CHECK-FIXES: std::println("Double {:#f} {:#F}", -42.0, -42.0); 571 572 printf("Double %#g %#G\n", -42.0, -42.0); 573 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 574 // CHECK-FIXES: std::println("Double {:#g} {:#G}", -42.0, -42.0); 575 576 printf("Double %#e %#E\n", -42.0, -42.0); 577 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 578 // CHECK-FIXES: std::println("Double {:#e} {:#E}", -42.0, -42.0); 579 580 printf("Double %#a %#A\n", -42.0, -42.0); 581 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 582 // CHECK-FIXES: std::println("Double {:#a} {:#A}", -42.0, -42.0); 583 584 // Characters don't have an alternate form 585 printf("Char %#c\n", 'A'); 586 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 587 // CHECK-FIXES: std::println("Char {}", 'A'); 588 589 // Strings don't have an alternate form 590 printf("Char %#c\n", 'A'); 591 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 592 // CHECK-FIXES: std::println("Char {}", 'A'); 593 } 594 595 void printf_string() { 596 printf("Hello %s after\n", "Goodbye"); 597 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 598 // CHECK-FIXES: std::println("Hello {} after", "Goodbye"); 599 600 // std::print can't print signed char strings. 601 const signed char *sstring = reinterpret_cast<const signed char *>("ustring"); 602 printf("signed char string %s\n", sstring); 603 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 604 // CHECK-FIXES: std::println("signed char string {}", reinterpret_cast<const char *>(sstring)); 605 606 // std::print can't print unsigned char strings. 607 const unsigned char *ustring = reinterpret_cast<const unsigned char *>("ustring"); 608 printf("unsigned char string %s\n", ustring); 609 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 610 // CHECK-FIXES: std::println("unsigned char string {}", reinterpret_cast<const char *>(ustring)); 611 } 612 613 void printf_float() { 614 // If the type is not specified then either f or e will be used depending on 615 // whichever is shorter. This means that it is necessary to be specific to 616 // maintain compatibility with printf. 617 618 // TODO: Should we force a cast here, since printf will promote to double 619 // automatically, but std::format will not, which could result in different 620 // output? 621 622 const float f = 42.0F; 623 printf("Hello %f after\n", f); 624 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 625 // CHECK-FIXES: std::println("Hello {:f} after", f); 626 627 printf("Hello %g after\n", f); 628 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 629 // CHECK-FIXES: std::println("Hello {:g} after", f); 630 631 printf("Hello %e after\n", f); 632 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 633 // CHECK-FIXES: std::println("Hello {:e} after", f); 634 } 635 636 void printf_double() { 637 // If the type is not specified then either f or e will be used depending on 638 // whichever is shorter. This means that it is necessary to be specific to 639 // maintain compatibility with printf. 640 641 const double d = 42.0; 642 printf("Hello %f after\n", d); 643 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 644 // CHECK-FIXES: std::println("Hello {:f} after", d); 645 646 printf("Hello %g after\n", d); 647 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 648 // CHECK-FIXES: std::println("Hello {:g} after", d); 649 650 printf("Hello %e after\n", d); 651 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 652 // CHECK-FIXES: std::println("Hello {:e} after", d); 653 } 654 655 void printf_long_double() { 656 // If the type is not specified then either f or e will be used depending on 657 // whichever is shorter. This means that it is necessary to be specific to 658 // maintain compatibility with printf. 659 660 const long double ld = 42.0L; 661 printf("Hello %Lf after\n", ld); 662 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 663 // CHECK-FIXES: std::println("Hello {:f} after", ld); 664 665 printf("Hello %g after\n", ld); 666 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 667 // CHECK-FIXES: std::println("Hello {:g} after", ld); 668 669 printf("Hello %e after\n", ld); 670 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 671 // CHECK-FIXES: std::println("Hello {:e} after", ld); 672 } 673 674 void printf_pointer() { 675 int i; 676 double j; 677 printf("Int* %p %s %p\n", &i, "Double*", &j); 678 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 679 // CHECK-FIXES: std::println("Int* {} {} {}", static_cast<const void *>(&i), "Double*", static_cast<const void *>(&j)); 680 681 printf("%p\n", nullptr); 682 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 683 // CHECK-FIXES: std::println("{}", nullptr); 684 685 const auto np = nullptr; 686 printf("%p\n", np); 687 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 688 // CHECK-FIXES: std::println("{}", np); 689 690 // NULL isn't a pointer, so std::print needs some help. 691 printf("%p\n", NULL); 692 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 693 // CHECK-FIXES: std::println("{}", static_cast<const void *>(NULL)); 694 695 printf("%p\n", 42); 696 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 697 // CHECK-FIXES: std::println("{}", static_cast<const void *>(42)); 698 699 // If we already have a void pointer then no cast is required. 700 printf("%p\n", reinterpret_cast<const void *>(44)); 701 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 702 // CHECK-FIXES: std::println("{}", reinterpret_cast<const void *>(44)); 703 704 const void *p; 705 printf("%p\n", p); 706 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 707 // CHECK-FIXES: std::println("{}", p); 708 709 // But a pointer to a pointer to void does need a cast 710 const void **pp; 711 printf("%p\n", pp); 712 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 713 // CHECK-FIXES: std::println("{}", static_cast<const void *>(pp)); 714 715 printf("%p\n", printf_pointer); 716 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 717 // CHECK-FIXES: std::println("{}", static_cast<const void *>(printf_pointer)); 718 } 719 720 class AClass 721 { 722 int member; 723 724 void printf_this_pointer() 725 { 726 printf("%p\n", this); 727 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 728 // CHECK-FIXES: std::println("{}", static_cast<const void *>(this)); 729 } 730 731 void printf_pointer_to_member_function() 732 { 733 printf("%p\n", &AClass::printf_pointer_to_member_function); 734 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 735 // CHECK-FIXES: std::println("{}", static_cast<const void *>(&AClass::printf_pointer_to_member_function)); 736 } 737 738 void printf_pointer_to_member_variable() 739 { 740 printf("%p\n", &AClass::member); 741 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 742 // CHECK-FIXES: std::println("{}", static_cast<const void *>(&AClass::member)); 743 } 744 }; 745 746 void printf_positional_arg() { 747 printf("%1$d", 42); 748 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 749 // CHECK-FIXES: std::print("{0}", 42); 750 751 printf("before %1$d", 42); 752 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 753 // CHECK-FIXES: std::print("before {0}", 42); 754 755 printf("%1$d after", 42); 756 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 757 // CHECK-FIXES: std::print("{0} after", 42); 758 759 printf("before %1$d after", 42); 760 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 761 // CHECK-FIXES: std::print("before {0} after", 42); 762 763 printf("before %2$d between %1$s after", "string", 42); 764 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 765 // CHECK-FIXES: std::print("before {1} between {0} after", "string", 42); 766 } 767 768 // printf always defaults to right justification,, no matter what the type is of 769 // the argument. std::format uses left justification by default for strings, and 770 // right justification for numbers. 771 void printf_right_justified() { 772 printf("Right-justified integer %4d after\n", 42); 773 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 774 // CHECK-FIXES: std::println("Right-justified integer {:4} after", 42); 775 776 printf("Right-justified double %4f\n", 227.2); 777 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 778 // CHECK-FIXES: std::println("Right-justified double {:4f}", 227.2); 779 780 printf("Right-justified double %4g\n", 227.4); 781 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 782 // CHECK-FIXES: std::println("Right-justified double {:4g}", 227.4); 783 784 printf("Right-justified integer with field width argument %*d after\n", 5, 424242); 785 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 786 // CHECK-FIXES: std::println("Right-justified integer with field width argument {:{}} after", 5, 424242); 787 788 printf("Right-justified integer with field width argument %2$*1$d after\n", 5, 424242); 789 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 790 // CHECK-FIXES: std::println("Right-justified integer with field width argument {1:{0}} after", 5, 424242); 791 792 printf("Right-justified string %20s\n", "Hello"); 793 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 794 // CHECK-FIXES: std::println("Right-justified string {:>20}", "Hello"); 795 796 printf("Right-justified string with field width argument %2$*1$s after\n", 20, "wibble"); 797 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 798 // CHECK-FIXES: std::println("Right-justified string with field width argument {1:>{0}} after", 20, "wibble"); 799 } 800 801 // printf always requires - for left justification, no matter what the type is 802 // of the argument. std::format uses left justification by default for strings, 803 // and right justification for numbers. 804 void printf_left_justified() { 805 printf("Left-justified integer %-4d\n", 42); 806 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 807 // CHECK-FIXES: std::println("Left-justified integer {:<4}", 42); 808 809 printf("Left-justified integer %--4d\n", 42); 810 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 811 // CHECK-FIXES: std::println("Left-justified integer {:<4}", 42); 812 813 printf("Left-justified double %-4f\n", 227.2); 814 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 815 // CHECK-FIXES: std::println("Left-justified double {:<4f}", 227.2); 816 817 printf("Left-justified double %-4g\n", 227.4); 818 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 819 // CHECK-FIXES: std::println("Left-justified double {:<4g}", 227.4); 820 821 printf("Left-justified integer with field width argument %-*d after\n", 5, 424242); 822 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 823 // CHECK-FIXES: std::println("Left-justified integer with field width argument {:<{}} after", 5, 424242); 824 825 printf("Left-justified integer with field width argument %2$-*1$d after\n", 5, 424242); 826 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 827 // CHECK-FIXES: std::println("Left-justified integer with field width argument {1:<{0}} after", 5, 424242); 828 829 printf("Left-justified string %-20s\n", "Hello"); 830 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 831 // CHECK-FIXES: std::println("Left-justified string {:20}", "Hello"); 832 833 printf("Left-justified string with field width argument %2$-*1$s after\n", 5, "wibble"); 834 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 835 // CHECK-FIXES: std::println("Left-justified string with field width argument {1:{0}} after", 5, "wibble"); 836 } 837 838 void printf_precision() { 839 printf("Hello %.3f\n", 3.14159); 840 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 841 // CHECK-FIXES: std::println("Hello {:.3f}", 3.14159); 842 843 printf("Hello %10.3f\n", 3.14159); 844 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 845 // CHECK-FIXES: std::println("Hello {:10.3f}", 3.14159); 846 847 printf("Hello %.*f after\n", 10, 3.14159265358979323846); 848 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 849 // CHECK-FIXES: std::println("Hello {:.{}f} after", 10, 3.14159265358979323846); 850 851 printf("Hello %10.*f after\n", 3, 3.14159265358979323846); 852 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 853 // CHECK-FIXES: std::println("Hello {:10.{}f} after", 3, 3.14159265358979323846); 854 855 printf("Hello %*.*f after\n", 10, 4, 3.14159265358979323846); 856 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 857 // CHECK-FIXES: std::println("Hello {:{}.{}f} after", 10, 4, 3.14159265358979323846); 858 859 printf("Hello %1$.*2$f after\n", 3.14159265358979323846, 4); 860 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 861 // CHECK-FIXES: std::println("Hello {0:.{1}f} after", 3.14159265358979323846, 4); 862 863 // Precision is ignored, but maintained on non-numeric arguments 864 printf("Hello %.5s\n", "Goodbye"); 865 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 866 // CHECK-FIXES: std::println("Hello {:.5}", "Goodbye"); 867 868 printf("Hello %.5c\n", 'G'); 869 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 870 // CHECK-FIXES: std::println("Hello {:.5}", 'G'); 871 } 872 873 void printf_field_width_and_precision() { 874 printf("Hello %1$*2$.*3$f after\n", 3.14159265358979323846, 4, 2); 875 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 876 // CHECK-FIXES: std::println("Hello {0:{1}.{2}f} after", 3.14159265358979323846, 4, 2); 877 } 878 879 void printf_alternative_form() { 880 printf("Wibble %#x\n", 42); 881 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 882 // CHECK-FIXES: std::println("Wibble {:#x}", 42); 883 884 printf("Wibble %#20x\n", 42); 885 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 886 // CHECK-FIXES: std::println("Wibble {:#20x}", 42); 887 888 printf("Wibble %#020x\n", 42); 889 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 890 // CHECK-FIXES: std::println("Wibble {:#020x}", 42); 891 892 printf("Wibble %#-20x\n", 42); 893 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 894 // CHECK-FIXES: std::println("Wibble {:<#20x}", 42); 895 } 896 897 void printf_leading_plus() { 898 printf("Positive integer %+d\n", 42); 899 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 900 // CHECK-FIXES: std::println("Positive integer {:+}", 42); 901 902 printf("Positive double %+f\n", 42.2); 903 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 904 // CHECK-FIXES: std::println("Positive double {:+f}", 42.2); 905 906 printf("Positive double %+g\n", 42.2); 907 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 908 // CHECK-FIXES: std::println("Positive double {:+g}", 42.2); 909 910 // Ignore leading plus on strings to avoid potential runtime exception where 911 // printf would have just ignored it. 912 printf("Positive string %+s\n", "string"); 913 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 914 // CHECK-FIXES: std::println("Positive string {}", "string"); 915 } 916 917 void printf_leading_space() { 918 printf("Spaced integer % d\n", 42); 919 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 920 // CHECK-FIXES: std::println("Spaced integer {: }", 42); 921 922 printf("Spaced integer %- d\n", 42); 923 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 924 // CHECK-FIXES: std::println("Spaced integer {: }", 42); 925 926 printf("Spaced double % f\n", 42.2); 927 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 928 // CHECK-FIXES: std::println("Spaced double {: f}", 42.2); 929 930 printf("Spaced double % g\n", 42.2); 931 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 932 // CHECK-FIXES: std::println("Spaced double {: g}", 42.2); 933 } 934 935 void printf_leading_zero() { 936 printf("Leading zero integer %03d\n", 42); 937 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 938 // CHECK-FIXES: std::println("Leading zero integer {:03}", 42); 939 940 printf("Leading minus and zero integer %-03d minus ignored\n", 42); 941 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 942 // CHECK-FIXES: std::println("Leading minus and zero integer {:<03} minus ignored", 42); 943 944 printf("Leading zero unsigned integer %03u\n", 42U); 945 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 946 // CHECK-FIXES: std::println("Leading zero unsigned integer {:03}", 42U); 947 948 printf("Leading zero double %03f\n", 42.2); 949 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 950 // CHECK-FIXES: std::println("Leading zero double {:03f}", 42.2); 951 952 printf("Leading zero double %03g\n", 42.2); 953 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 954 // CHECK-FIXES: std::println("Leading zero double {:03g}", 42.2); 955 } 956 957 void printf_leading_plus_and_space() { 958 // printf prefers plus to space. {fmt} will throw if both are present. 959 printf("Spaced integer % +d\n", 42); 960 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 961 // CHECK-FIXES: std::println("Spaced integer {:+}", 42); 962 963 printf("Spaced double %+ f\n", 42.2); 964 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 965 // CHECK-FIXES: std::println("Spaced double {:+f}", 42.2); 966 967 printf("Spaced double % +g\n", 42.2); 968 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 969 // CHECK-FIXES: std::println("Spaced double {:+g}", 42.2); 970 } 971 972 void printf_leading_zero_and_plus() { 973 printf("Leading zero integer %+03d\n", 42); 974 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 975 // CHECK-FIXES: std::println("Leading zero integer {:+03}", 42); 976 977 printf("Leading zero double %0+3f\n", 42.2); 978 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 979 // CHECK-FIXES: std::println("Leading zero double {:+03f}", 42.2); 980 981 printf("Leading zero double %0+3g\n", 42.2); 982 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 983 // CHECK-FIXES: std::println("Leading zero double {:+03g}", 42.2); 984 } 985 986 void printf_leading_zero_and_space() { 987 printf("Leading zero and space integer %0 3d\n", 42); 988 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 989 // CHECK-FIXES: std::println("Leading zero and space integer {: 03}", 42); 990 991 printf("Leading zero and space double %0 3f\n", 42.2); 992 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 993 // CHECK-FIXES: std::println("Leading zero and space double {: 03f}", 42.2); 994 995 printf("Leading zero and space double %0 3g\n", 42.2); 996 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 997 // CHECK-FIXES: std::println("Leading zero and space double {: 03g}", 42.2); 998 } 999 1000 // add signed plained enum too 1001 enum PlainEnum { red }; 1002 enum SignedPlainEnum { black = -42 }; 1003 enum BoolEnum : unsigned int { yellow }; 1004 enum CharEnum : char { purple }; 1005 enum SCharEnum : signed char { aquamarine }; 1006 enum UCharEnum : unsigned char { pink }; 1007 enum ShortEnum : short { beige }; 1008 enum UShortEnum : unsigned short { grey }; 1009 enum IntEnum : int { green }; 1010 enum UIntEnum : unsigned int { blue }; 1011 enum LongEnum : long { magenta }; 1012 enum ULongEnum : unsigned long { cyan }; 1013 enum LongLongEnum : long long { taupe }; 1014 enum ULongLongEnum : unsigned long long { brown }; 1015 1016 void printf_enum_d() { 1017 PlainEnum plain_enum; 1018 printf("%d", plain_enum); 1019 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1020 // CHECK-FIXES: std::print("{}", static_cast<int>(plain_enum)); 1021 1022 SignedPlainEnum splain_enum; 1023 printf("%d", splain_enum); 1024 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1025 // CHECK-FIXES: std::print("{}", static_cast<int>(splain_enum)); 1026 1027 BoolEnum bool_enum; 1028 printf("%d", bool_enum); 1029 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1030 // CHECK-FIXES: std::print("{}", static_cast<int>(bool_enum)); 1031 1032 CharEnum char_enum; 1033 printf("%d", char_enum); 1034 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1035 // CHECK-FIXES: std::print("{}", static_cast<signed char>(char_enum)); 1036 1037 SCharEnum schar_enum; 1038 printf("%d", schar_enum); 1039 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1040 // CHECK-FIXES: std::print("{}", static_cast<signed char>(schar_enum)); 1041 1042 UCharEnum uchar_enum; 1043 printf("%d", uchar_enum); 1044 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1045 // CHECK-FIXES: std::print("{}", static_cast<signed char>(uchar_enum)); 1046 1047 ShortEnum short_enum; 1048 printf("%d", short_enum); 1049 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1050 // CHECK-FIXES: std::print("{}", static_cast<short>(short_enum)); 1051 1052 UShortEnum ushort_enum; 1053 printf("%d", ushort_enum); 1054 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1055 // CHECK-FIXES: std::print("{}", static_cast<short>(ushort_enum)); 1056 1057 IntEnum int_enum; 1058 printf("%d", int_enum); 1059 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1060 // CHECK-FIXES: std::print("{}", static_cast<int>(int_enum)); 1061 1062 UIntEnum uint_enum; 1063 printf("%d", uint_enum); 1064 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1065 // CHECK-FIXES: std::print("{}", static_cast<int>(uint_enum)); 1066 1067 LongEnum long_enum; 1068 printf("%d", long_enum); 1069 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1070 // CHECK-FIXES: std::print("{}", static_cast<long>(long_enum)); 1071 1072 ULongEnum ulong_enum; 1073 printf("%d", ulong_enum); 1074 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1075 // CHECK-FIXES: std::print("{}", static_cast<long>(ulong_enum)); 1076 1077 LongLongEnum longlong_enum; 1078 printf("%d", longlong_enum); 1079 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1080 // CHECK-FIXES: std::print("{}", static_cast<long long>(longlong_enum)); 1081 1082 ULongLongEnum ulonglong_enum; 1083 printf("%d", ulonglong_enum); 1084 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1085 // CHECK-FIXES: std::print("{}", static_cast<long long>(ulonglong_enum)); 1086 } 1087 1088 void printf_enum_u() { 1089 PlainEnum plain_enum; 1090 printf("%u", plain_enum); 1091 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1092 // CHECK-FIXES: std::print("{}", static_cast<unsigned int>(plain_enum)); 1093 1094 SignedPlainEnum splain_enum; 1095 printf("%u", splain_enum); 1096 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1097 // CHECK-FIXES: std::print("{}", static_cast<unsigned int>(splain_enum)); 1098 1099 BoolEnum bool_enum; 1100 printf("%u", bool_enum); 1101 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1102 // CHECK-FIXES: std::print("{}", static_cast<unsigned int>(bool_enum)); 1103 1104 CharEnum char_enum; 1105 printf("%u", char_enum); 1106 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1107 // CHECK-FIXES: std::print("{}", static_cast<unsigned char>(char_enum)); 1108 1109 SCharEnum schar_enum; 1110 printf("%u", schar_enum); 1111 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1112 // CHECK-FIXES: std::print("{}", static_cast<unsigned char>(schar_enum)); 1113 1114 UCharEnum uchar_enum; 1115 printf("%u", uchar_enum); 1116 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1117 // CHECK-FIXES: std::print("{}", static_cast<unsigned char>(uchar_enum)); 1118 1119 ShortEnum short_enum; 1120 printf("%u", short_enum); 1121 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1122 // CHECK-FIXES: std::print("{}", static_cast<unsigned short>(short_enum)); 1123 1124 UShortEnum ushort_enum; 1125 printf("%u", ushort_enum); 1126 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1127 // CHECK-FIXES: std::print("{}", static_cast<unsigned short>(ushort_enum)); 1128 1129 IntEnum int_enum; 1130 printf("%u", int_enum); 1131 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1132 // CHECK-FIXES: std::print("{}", static_cast<unsigned int>(int_enum)); 1133 1134 UIntEnum uint_enum; 1135 printf("%u", uint_enum); 1136 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1137 // CHECK-FIXES: std::print("{}", static_cast<unsigned int>(uint_enum)); 1138 1139 LongEnum long_enum; 1140 printf("%u", long_enum); 1141 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1142 // CHECK-FIXES: std::print("{}", static_cast<unsigned long>(long_enum)); 1143 1144 ULongEnum ulong_enum; 1145 printf("%u", ulong_enum); 1146 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1147 // CHECK-FIXES: std::print("{}", static_cast<unsigned long>(ulong_enum)); 1148 1149 LongLongEnum longlong_enum; 1150 printf("%u", longlong_enum); 1151 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1152 // CHECK-FIXES: std::print("{}", static_cast<unsigned long long>(longlong_enum)); 1153 1154 ULongLongEnum ulonglong_enum; 1155 printf("%u", ulonglong_enum); 1156 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1157 // CHECK-FIXES: std::print("{}", static_cast<unsigned long long>(ulonglong_enum)); 1158 } 1159 1160 void printf_string_function(const char *(*callback)()) { 1161 printf("printf string from callback %s", callback()); 1162 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1163 // CHECK-FIXES: std::print("printf string from callback {}", callback()); 1164 } 1165 1166 template <typename CharType> 1167 struct X 1168 { 1169 const CharType *str() const; 1170 }; 1171 1172 void printf_string_member_function(const X<char> &x, const X<const char> &cx) { 1173 printf("printf string from member function %s", x.str()); 1174 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1175 // CHECK-FIXES: std::print("printf string from member function {}", x.str()); 1176 1177 printf("printf string from member function on const %s", cx.str()); 1178 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1179 // CHECK-FIXES: std::print("printf string from member function on const {}", cx.str()); 1180 } 1181 1182 void printf_string_cstr(const std::string &s1, const std::string &s2) { 1183 printf("printf string one c_str %s", s1.c_str()); 1184 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1185 // CHECK-FIXES: std::print("printf string one c_str {}", s1); 1186 1187 printf("printf string two c_str %s %s\n", s1.c_str(), s2.data()); 1188 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1189 // CHECK-FIXES: std::println("printf string two c_str {} {}", s1, s2); 1190 } 1191 1192 void printf_not_char_string_cstr(const std::wstring &ws1) { 1193 // This test is to check that we only remove 1194 // std::basic_string<CharType>::c_str()/data() when CharType is char. I've 1195 // been unable to come up with a genuine situation where someone would have 1196 // actually successfully called those methods when this isn't the case without 1197 // -Wformat warning, but it seems sensible to restrict removal regardless. 1198 printf("printf bogus wstring c_str %s", ws1.c_str()); 1199 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1200 // CHECK-FIXES: std::print("printf bogus wstring c_str {}", ws1.c_str()); 1201 } 1202 1203 void fprintf_string_cstr(const std::string &s1) { 1204 fprintf(stderr, "fprintf string c_str %s", s1.c_str()); 1205 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'fprintf' [modernize-use-std-print] 1206 // CHECK-FIXES: std::print(stderr, "fprintf string c_str {}", s1); 1207 } 1208 1209 void printf_string_pointer_cstr(const std::string *s1, const std::string *s2) { 1210 printf("printf string pointer one c_str %s", s1->c_str()); 1211 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1212 // CHECK-FIXES: std::print("printf string pointer one c_str {}", *s1); 1213 1214 printf("printf string pointer two c_str %s %s\n", s1->c_str(), s2->data()); 1215 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1216 // CHECK-FIXES: std::println("printf string pointer two c_str {} {}", *s1, *s2); 1217 } 1218 1219 void fprintf_string_pointer_cstr(const std::string *s1) { 1220 fprintf(stderr, "fprintf string pointer c_str %s", s1->c_str()); 1221 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'fprintf' [modernize-use-std-print] 1222 // CHECK-FIXES: std::print(stderr, "fprintf string pointer c_str {}", *s1); 1223 } 1224 1225 template <typename T> 1226 struct iterator { 1227 T *operator->(); 1228 T &operator*(); 1229 }; 1230 1231 void printf_iterator_cstr(iterator<std::string> i1, iterator<std::string> i2) 1232 { 1233 printf("printf iterator c_str %s %s\n", i1->c_str(), i2->data()); 1234 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 1235 // CHECK-FIXES: std::println("printf iterator c_str {} {}", *i1, *i2); 1236 } 1237 1238 // Something that isn't std::string, so the calls to c_str() and data() must not 1239 // be removed even though the printf call will be replaced. 1240 struct S 1241 { 1242 const char *c_str() const; 1243 const char *data() const; 1244 }; 1245 1246 void p(S s1, S *s2) 1247 { 1248 printf("Not std::string %s %s", s1.c_str(), s2->c_str()); 1249 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1250 // CHECK-FIXES: std::print("Not std::string {} {}", s1.c_str(), s2->c_str()); 1251 1252 printf("Not std::string %s %s", s1.data(), s2->data()); 1253 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print] 1254 // CHECK-FIXES: std::print("Not std::string {} {}", s1.data(), s2->data()); 1255 } 1256