1 //== PrintfFormatString.cpp - Analysis of printf format strings --*- C++ -*-==//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Handling of format string in printf and friends. The structure of format
11 // strings for fprintf() are described in C99 7.19.6.1.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "clang/AST/FormatString.h"
16 #include "clang/AST/OSLog.h"
17 #include "FormatStringParsing.h"
18 #include "clang/Basic/TargetInfo.h"
19
20 using clang::analyze_format_string::ArgType;
21 using clang::analyze_format_string::FormatStringHandler;
22 using clang::analyze_format_string::LengthModifier;
23 using clang::analyze_format_string::OptionalAmount;
24 using clang::analyze_format_string::ConversionSpecifier;
25 using clang::analyze_printf::PrintfSpecifier;
26
27 using namespace clang;
28
29 typedef clang::analyze_format_string::SpecifierResult<PrintfSpecifier>
30 PrintfSpecifierResult;
31
32 //===----------------------------------------------------------------------===//
33 // Methods for parsing format strings.
34 //===----------------------------------------------------------------------===//
35
36 using analyze_format_string::ParseNonPositionAmount;
37
ParsePrecision(FormatStringHandler & H,PrintfSpecifier & FS,const char * Start,const char * & Beg,const char * E,unsigned * argIndex)38 static bool ParsePrecision(FormatStringHandler &H, PrintfSpecifier &FS,
39 const char *Start, const char *&Beg, const char *E,
40 unsigned *argIndex) {
41 if (argIndex) {
42 FS.setPrecision(ParseNonPositionAmount(Beg, E, *argIndex));
43 } else {
44 const OptionalAmount Amt = ParsePositionAmount(H, Start, Beg, E,
45 analyze_format_string::PrecisionPos);
46 if (Amt.isInvalid())
47 return true;
48 FS.setPrecision(Amt);
49 }
50 return false;
51 }
52
ParseObjCFlags(FormatStringHandler & H,PrintfSpecifier & FS,const char * FlagBeg,const char * E,bool Warn)53 static bool ParseObjCFlags(FormatStringHandler &H, PrintfSpecifier &FS,
54 const char *FlagBeg, const char *E, bool Warn) {
55 StringRef Flag(FlagBeg, E - FlagBeg);
56 // Currently there is only one flag.
57 if (Flag == "tt") {
58 FS.setHasObjCTechnicalTerm(FlagBeg);
59 return false;
60 }
61 // Handle either the case of no flag or an invalid flag.
62 if (Warn) {
63 if (Flag == "")
64 H.HandleEmptyObjCModifierFlag(FlagBeg, E - FlagBeg);
65 else
66 H.HandleInvalidObjCModifierFlag(FlagBeg, E - FlagBeg);
67 }
68 return true;
69 }
70
ParsePrintfSpecifier(FormatStringHandler & H,const char * & Beg,const char * E,unsigned & argIndex,const LangOptions & LO,const TargetInfo & Target,bool Warn,bool isFreeBSDKPrintf)71 static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
72 const char *&Beg,
73 const char *E,
74 unsigned &argIndex,
75 const LangOptions &LO,
76 const TargetInfo &Target,
77 bool Warn,
78 bool isFreeBSDKPrintf) {
79
80 using namespace clang::analyze_format_string;
81 using namespace clang::analyze_printf;
82
83 const char *I = Beg;
84 const char *Start = nullptr;
85 UpdateOnReturn <const char*> UpdateBeg(Beg, I);
86
87 // Look for a '%' character that indicates the start of a format specifier.
88 for ( ; I != E ; ++I) {
89 char c = *I;
90 if (c == '\0') {
91 // Detect spurious null characters, which are likely errors.
92 H.HandleNullChar(I);
93 return true;
94 }
95 if (c == '%') {
96 Start = I++; // Record the start of the format specifier.
97 break;
98 }
99 }
100
101 // No format specifier found?
102 if (!Start)
103 return false;
104
105 if (I == E) {
106 // No more characters left?
107 if (Warn)
108 H.HandleIncompleteSpecifier(Start, E - Start);
109 return true;
110 }
111
112 PrintfSpecifier FS;
113 if (ParseArgPosition(H, FS, Start, I, E))
114 return true;
115
116 if (I == E) {
117 // No more characters left?
118 if (Warn)
119 H.HandleIncompleteSpecifier(Start, E - Start);
120 return true;
121 }
122
123 if (*I == '{') {
124 ++I;
125 unsigned char PrivacyFlags = 0;
126 StringRef MatchedStr;
127
128 do {
129 StringRef Str(I, E - I);
130 std::string Match = "^[[:space:]]*"
131 "(private|public|sensitive|mask\\.[^[:space:],}]*)"
132 "[[:space:]]*(,|})";
133 llvm::Regex R(Match);
134 SmallVector<StringRef, 2> Matches;
135
136 if (R.match(Str, &Matches)) {
137 MatchedStr = Matches[1];
138 I += Matches[0].size();
139
140 // Set the privacy flag if the privacy annotation in the
141 // comma-delimited segment is at least as strict as the privacy
142 // annotations in previous comma-delimited segments.
143 if (MatchedStr.startswith("mask")) {
144 StringRef MaskType = MatchedStr.substr(sizeof("mask.") - 1);
145 unsigned Size = MaskType.size();
146 if (Warn && (Size == 0 || Size > 8))
147 H.handleInvalidMaskType(MaskType);
148 FS.setMaskType(MaskType);
149 } else if (MatchedStr.equals("sensitive"))
150 PrivacyFlags = clang::analyze_os_log::OSLogBufferItem::IsSensitive;
151 else if (PrivacyFlags !=
152 clang::analyze_os_log::OSLogBufferItem::IsSensitive &&
153 MatchedStr.equals("private"))
154 PrivacyFlags = clang::analyze_os_log::OSLogBufferItem::IsPrivate;
155 else if (PrivacyFlags == 0 && MatchedStr.equals("public"))
156 PrivacyFlags = clang::analyze_os_log::OSLogBufferItem::IsPublic;
157 } else {
158 size_t CommaOrBracePos =
159 Str.find_if([](char c) { return c == ',' || c == '}'; });
160
161 if (CommaOrBracePos == StringRef::npos) {
162 // Neither a comma nor the closing brace was found.
163 if (Warn)
164 H.HandleIncompleteSpecifier(Start, E - Start);
165 return true;
166 }
167
168 I += CommaOrBracePos + 1;
169 }
170 // Continue until the closing brace is found.
171 } while (*(I - 1) == ',');
172
173 // Set the privacy flag.
174 switch (PrivacyFlags) {
175 case 0:
176 break;
177 case clang::analyze_os_log::OSLogBufferItem::IsPrivate:
178 FS.setIsPrivate(MatchedStr.data());
179 break;
180 case clang::analyze_os_log::OSLogBufferItem::IsPublic:
181 FS.setIsPublic(MatchedStr.data());
182 break;
183 case clang::analyze_os_log::OSLogBufferItem::IsSensitive:
184 FS.setIsSensitive(MatchedStr.data());
185 break;
186 default:
187 llvm_unreachable("Unexpected privacy flag value");
188 }
189 }
190
191 // Look for flags (if any).
192 bool hasMore = true;
193 for ( ; I != E; ++I) {
194 switch (*I) {
195 default: hasMore = false; break;
196 case '\'':
197 // FIXME: POSIX specific. Always accept?
198 FS.setHasThousandsGrouping(I);
199 break;
200 case '-': FS.setIsLeftJustified(I); break;
201 case '+': FS.setHasPlusPrefix(I); break;
202 case ' ': FS.setHasSpacePrefix(I); break;
203 case '#': FS.setHasAlternativeForm(I); break;
204 case '0': FS.setHasLeadingZeros(I); break;
205 }
206 if (!hasMore)
207 break;
208 }
209
210 if (I == E) {
211 // No more characters left?
212 if (Warn)
213 H.HandleIncompleteSpecifier(Start, E - Start);
214 return true;
215 }
216
217 // Look for the field width (if any).
218 if (ParseFieldWidth(H, FS, Start, I, E,
219 FS.usesPositionalArg() ? nullptr : &argIndex))
220 return true;
221
222 if (I == E) {
223 // No more characters left?
224 if (Warn)
225 H.HandleIncompleteSpecifier(Start, E - Start);
226 return true;
227 }
228
229 // Look for the precision (if any).
230 if (*I == '.') {
231 ++I;
232 if (I == E) {
233 if (Warn)
234 H.HandleIncompleteSpecifier(Start, E - Start);
235 return true;
236 }
237
238 if (ParsePrecision(H, FS, Start, I, E,
239 FS.usesPositionalArg() ? nullptr : &argIndex))
240 return true;
241
242 if (I == E) {
243 // No more characters left?
244 if (Warn)
245 H.HandleIncompleteSpecifier(Start, E - Start);
246 return true;
247 }
248 }
249
250 if (ParseVectorModifier(H, FS, I, E, LO))
251 return true;
252
253 // Look for the length modifier.
254 if (ParseLengthModifier(FS, I, E, LO) && I == E) {
255 // No more characters left?
256 if (Warn)
257 H.HandleIncompleteSpecifier(Start, E - Start);
258 return true;
259 }
260
261 // Look for the Objective-C modifier flags, if any.
262 // We parse these here, even if they don't apply to
263 // the conversion specifier, and then emit an error
264 // later if the conversion specifier isn't '@'. This
265 // enables better recovery, and we don't know if
266 // these flags are applicable until later.
267 const char *ObjCModifierFlagsStart = nullptr,
268 *ObjCModifierFlagsEnd = nullptr;
269 if (*I == '[') {
270 ObjCModifierFlagsStart = I;
271 ++I;
272 auto flagStart = I;
273 for (;; ++I) {
274 ObjCModifierFlagsEnd = I;
275 if (I == E) {
276 if (Warn)
277 H.HandleIncompleteSpecifier(Start, E - Start);
278 return true;
279 }
280 // Did we find the closing ']'?
281 if (*I == ']') {
282 if (ParseObjCFlags(H, FS, flagStart, I, Warn))
283 return true;
284 ++I;
285 break;
286 }
287 // There are no separators defined yet for multiple
288 // Objective-C modifier flags. When those are
289 // defined, this is the place to check.
290 }
291 }
292
293 if (*I == '\0') {
294 // Detect spurious null characters, which are likely errors.
295 H.HandleNullChar(I);
296 return true;
297 }
298
299 // Finally, look for the conversion specifier.
300 const char *conversionPosition = I++;
301 ConversionSpecifier::Kind k = ConversionSpecifier::InvalidSpecifier;
302 switch (*conversionPosition) {
303 default:
304 break;
305 // C99: 7.19.6.1 (section 8).
306 case '%': k = ConversionSpecifier::PercentArg; break;
307 case 'A': k = ConversionSpecifier::AArg; break;
308 case 'E': k = ConversionSpecifier::EArg; break;
309 case 'F': k = ConversionSpecifier::FArg; break;
310 case 'G': k = ConversionSpecifier::GArg; break;
311 case 'X': k = ConversionSpecifier::XArg; break;
312 case 'a': k = ConversionSpecifier::aArg; break;
313 case 'c': k = ConversionSpecifier::cArg; break;
314 case 'd': k = ConversionSpecifier::dArg; break;
315 case 'e': k = ConversionSpecifier::eArg; break;
316 case 'f': k = ConversionSpecifier::fArg; break;
317 case 'g': k = ConversionSpecifier::gArg; break;
318 case 'i': k = ConversionSpecifier::iArg; break;
319 case 'n': k = ConversionSpecifier::nArg; break;
320 case 'o': k = ConversionSpecifier::oArg; break;
321 case 'p': k = ConversionSpecifier::pArg; break;
322 case 's': k = ConversionSpecifier::sArg; break;
323 case 'u': k = ConversionSpecifier::uArg; break;
324 case 'x': k = ConversionSpecifier::xArg; break;
325 // POSIX specific.
326 case 'C': k = ConversionSpecifier::CArg; break;
327 case 'S': k = ConversionSpecifier::SArg; break;
328 // Apple extension for os_log
329 case 'P':
330 k = ConversionSpecifier::PArg;
331 break;
332 // Objective-C.
333 case '@': k = ConversionSpecifier::ObjCObjArg; break;
334 // Glibc specific.
335 case 'm': k = ConversionSpecifier::PrintErrno; break;
336 // FreeBSD kernel specific.
337 case 'b':
338 if (isFreeBSDKPrintf)
339 k = ConversionSpecifier::FreeBSDbArg; // int followed by char *
340 break;
341 case 'r':
342 if (isFreeBSDKPrintf)
343 k = ConversionSpecifier::FreeBSDrArg; // int
344 break;
345 case 'y':
346 if (isFreeBSDKPrintf)
347 k = ConversionSpecifier::FreeBSDyArg; // int
348 break;
349 // Apple-specific.
350 case 'D':
351 if (isFreeBSDKPrintf)
352 k = ConversionSpecifier::FreeBSDDArg; // void * followed by char *
353 else if (Target.getTriple().isOSDarwin())
354 k = ConversionSpecifier::DArg;
355 break;
356 case 'O':
357 if (Target.getTriple().isOSDarwin())
358 k = ConversionSpecifier::OArg;
359 break;
360 case 'U':
361 if (Target.getTriple().isOSDarwin())
362 k = ConversionSpecifier::UArg;
363 break;
364 // MS specific.
365 case 'Z':
366 if (Target.getTriple().isOSMSVCRT())
367 k = ConversionSpecifier::ZArg;
368 break;
369 }
370
371 // Check to see if we used the Objective-C modifier flags with
372 // a conversion specifier other than '@'.
373 if (k != ConversionSpecifier::ObjCObjArg &&
374 k != ConversionSpecifier::InvalidSpecifier &&
375 ObjCModifierFlagsStart) {
376 H.HandleObjCFlagsWithNonObjCConversion(ObjCModifierFlagsStart,
377 ObjCModifierFlagsEnd + 1,
378 conversionPosition);
379 return true;
380 }
381
382 PrintfConversionSpecifier CS(conversionPosition, k);
383 FS.setConversionSpecifier(CS);
384 if (CS.consumesDataArgument() && !FS.usesPositionalArg())
385 FS.setArgIndex(argIndex++);
386 // FreeBSD kernel specific.
387 if (k == ConversionSpecifier::FreeBSDbArg ||
388 k == ConversionSpecifier::FreeBSDDArg)
389 argIndex++;
390
391 if (k == ConversionSpecifier::InvalidSpecifier) {
392 unsigned Len = I - Start;
393 if (ParseUTF8InvalidSpecifier(Start, E, Len)) {
394 CS.setEndScanList(Start + Len);
395 FS.setConversionSpecifier(CS);
396 }
397 // Assume the conversion takes one argument.
398 return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, Len);
399 }
400 return PrintfSpecifierResult(Start, FS);
401 }
402
ParsePrintfString(FormatStringHandler & H,const char * I,const char * E,const LangOptions & LO,const TargetInfo & Target,bool isFreeBSDKPrintf)403 bool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H,
404 const char *I,
405 const char *E,
406 const LangOptions &LO,
407 const TargetInfo &Target,
408 bool isFreeBSDKPrintf) {
409
410 unsigned argIndex = 0;
411
412 // Keep looking for a format specifier until we have exhausted the string.
413 while (I != E) {
414 const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
415 LO, Target, true,
416 isFreeBSDKPrintf);
417 // Did a fail-stop error of any kind occur when parsing the specifier?
418 // If so, don't do any more processing.
419 if (FSR.shouldStop())
420 return true;
421 // Did we exhaust the string or encounter an error that
422 // we can recover from?
423 if (!FSR.hasValue())
424 continue;
425 // We have a format specifier. Pass it to the callback.
426 if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(),
427 I - FSR.getStart()))
428 return true;
429 }
430 assert(I == E && "Format string not exhausted");
431 return false;
432 }
433
ParseFormatStringHasSArg(const char * I,const char * E,const LangOptions & LO,const TargetInfo & Target)434 bool clang::analyze_format_string::ParseFormatStringHasSArg(const char *I,
435 const char *E,
436 const LangOptions &LO,
437 const TargetInfo &Target) {
438
439 unsigned argIndex = 0;
440
441 // Keep looking for a %s format specifier until we have exhausted the string.
442 FormatStringHandler H;
443 while (I != E) {
444 const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
445 LO, Target, false,
446 false);
447 // Did a fail-stop error of any kind occur when parsing the specifier?
448 // If so, don't do any more processing.
449 if (FSR.shouldStop())
450 return false;
451 // Did we exhaust the string or encounter an error that
452 // we can recover from?
453 if (!FSR.hasValue())
454 continue;
455 const analyze_printf::PrintfSpecifier &FS = FSR.getValue();
456 // Return true if this a %s format specifier.
457 if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::Kind::sArg)
458 return true;
459 }
460 return false;
461 }
462
463 //===----------------------------------------------------------------------===//
464 // Methods on PrintfSpecifier.
465 //===----------------------------------------------------------------------===//
466
getScalarArgType(ASTContext & Ctx,bool IsObjCLiteral) const467 ArgType PrintfSpecifier::getScalarArgType(ASTContext &Ctx,
468 bool IsObjCLiteral) const {
469 if (CS.getKind() == ConversionSpecifier::cArg)
470 switch (LM.getKind()) {
471 case LengthModifier::None:
472 return Ctx.IntTy;
473 case LengthModifier::AsLong:
474 case LengthModifier::AsWide:
475 return ArgType(ArgType::WIntTy, "wint_t");
476 case LengthModifier::AsShort:
477 if (Ctx.getTargetInfo().getTriple().isOSMSVCRT())
478 return Ctx.IntTy;
479 LLVM_FALLTHROUGH;
480 default:
481 return ArgType::Invalid();
482 }
483
484 if (CS.isIntArg())
485 switch (LM.getKind()) {
486 case LengthModifier::AsLongDouble:
487 // GNU extension.
488 return Ctx.LongLongTy;
489 case LengthModifier::None:
490 return Ctx.IntTy;
491 case LengthModifier::AsInt32:
492 return ArgType(Ctx.IntTy, "__int32");
493 case LengthModifier::AsChar: return ArgType::AnyCharTy;
494 case LengthModifier::AsShort: return Ctx.ShortTy;
495 case LengthModifier::AsLong: return Ctx.LongTy;
496 case LengthModifier::AsLongLong:
497 case LengthModifier::AsQuad:
498 return Ctx.LongLongTy;
499 case LengthModifier::AsInt64:
500 return ArgType(Ctx.LongLongTy, "__int64");
501 case LengthModifier::AsIntMax:
502 return ArgType(Ctx.getIntMaxType(), "intmax_t");
503 case LengthModifier::AsSizeT:
504 return ArgType::makeSizeT(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
505 case LengthModifier::AsInt3264:
506 return Ctx.getTargetInfo().getTriple().isArch64Bit()
507 ? ArgType(Ctx.LongLongTy, "__int64")
508 : ArgType(Ctx.IntTy, "__int32");
509 case LengthModifier::AsPtrDiff:
510 return ArgType::makePtrdiffT(
511 ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
512 case LengthModifier::AsAllocate:
513 case LengthModifier::AsMAllocate:
514 case LengthModifier::AsWide:
515 return ArgType::Invalid();
516 }
517
518 if (CS.isUIntArg())
519 switch (LM.getKind()) {
520 case LengthModifier::AsLongDouble:
521 // GNU extension.
522 return Ctx.UnsignedLongLongTy;
523 case LengthModifier::None:
524 return Ctx.UnsignedIntTy;
525 case LengthModifier::AsInt32:
526 return ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
527 case LengthModifier::AsChar: return Ctx.UnsignedCharTy;
528 case LengthModifier::AsShort: return Ctx.UnsignedShortTy;
529 case LengthModifier::AsLong: return Ctx.UnsignedLongTy;
530 case LengthModifier::AsLongLong:
531 case LengthModifier::AsQuad:
532 return Ctx.UnsignedLongLongTy;
533 case LengthModifier::AsInt64:
534 return ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64");
535 case LengthModifier::AsIntMax:
536 return ArgType(Ctx.getUIntMaxType(), "uintmax_t");
537 case LengthModifier::AsSizeT:
538 return ArgType::makeSizeT(ArgType(Ctx.getSizeType(), "size_t"));
539 case LengthModifier::AsInt3264:
540 return Ctx.getTargetInfo().getTriple().isArch64Bit()
541 ? ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64")
542 : ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
543 case LengthModifier::AsPtrDiff:
544 return ArgType::makePtrdiffT(
545 ArgType(Ctx.getUnsignedPointerDiffType(), "unsigned ptrdiff_t"));
546 case LengthModifier::AsAllocate:
547 case LengthModifier::AsMAllocate:
548 case LengthModifier::AsWide:
549 return ArgType::Invalid();
550 }
551
552 if (CS.isDoubleArg()) {
553 if (LM.getKind() == LengthModifier::AsLongDouble)
554 return Ctx.LongDoubleTy;
555 return Ctx.DoubleTy;
556 }
557
558 if (CS.getKind() == ConversionSpecifier::nArg) {
559 switch (LM.getKind()) {
560 case LengthModifier::None:
561 return ArgType::PtrTo(Ctx.IntTy);
562 case LengthModifier::AsChar:
563 return ArgType::PtrTo(Ctx.SignedCharTy);
564 case LengthModifier::AsShort:
565 return ArgType::PtrTo(Ctx.ShortTy);
566 case LengthModifier::AsLong:
567 return ArgType::PtrTo(Ctx.LongTy);
568 case LengthModifier::AsLongLong:
569 case LengthModifier::AsQuad:
570 return ArgType::PtrTo(Ctx.LongLongTy);
571 case LengthModifier::AsIntMax:
572 return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
573 case LengthModifier::AsSizeT:
574 return ArgType::PtrTo(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
575 case LengthModifier::AsPtrDiff:
576 return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
577 case LengthModifier::AsLongDouble:
578 return ArgType(); // FIXME: Is this a known extension?
579 case LengthModifier::AsAllocate:
580 case LengthModifier::AsMAllocate:
581 case LengthModifier::AsInt32:
582 case LengthModifier::AsInt3264:
583 case LengthModifier::AsInt64:
584 case LengthModifier::AsWide:
585 return ArgType::Invalid();
586 }
587 }
588
589 switch (CS.getKind()) {
590 case ConversionSpecifier::sArg:
591 if (LM.getKind() == LengthModifier::AsWideChar) {
592 if (IsObjCLiteral)
593 return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
594 "const unichar *");
595 return ArgType(ArgType::WCStrTy, "wchar_t *");
596 }
597 if (LM.getKind() == LengthModifier::AsWide)
598 return ArgType(ArgType::WCStrTy, "wchar_t *");
599 return ArgType::CStrTy;
600 case ConversionSpecifier::SArg:
601 if (IsObjCLiteral)
602 return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
603 "const unichar *");
604 if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
605 LM.getKind() == LengthModifier::AsShort)
606 return ArgType::CStrTy;
607 return ArgType(ArgType::WCStrTy, "wchar_t *");
608 case ConversionSpecifier::CArg:
609 if (IsObjCLiteral)
610 return ArgType(Ctx.UnsignedShortTy, "unichar");
611 if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
612 LM.getKind() == LengthModifier::AsShort)
613 return Ctx.IntTy;
614 return ArgType(Ctx.WideCharTy, "wchar_t");
615 case ConversionSpecifier::pArg:
616 case ConversionSpecifier::PArg:
617 return ArgType::CPointerTy;
618 case ConversionSpecifier::ObjCObjArg:
619 return ArgType::ObjCPointerTy;
620 default:
621 break;
622 }
623
624 // FIXME: Handle other cases.
625 return ArgType();
626 }
627
628
getArgType(ASTContext & Ctx,bool IsObjCLiteral) const629 ArgType PrintfSpecifier::getArgType(ASTContext &Ctx,
630 bool IsObjCLiteral) const {
631 const PrintfConversionSpecifier &CS = getConversionSpecifier();
632
633 if (!CS.consumesDataArgument())
634 return ArgType::Invalid();
635
636 ArgType ScalarTy = getScalarArgType(Ctx, IsObjCLiteral);
637 if (!ScalarTy.isValid() || VectorNumElts.isInvalid())
638 return ScalarTy;
639
640 return ScalarTy.makeVectorType(Ctx, VectorNumElts.getConstantAmount());
641 }
642
fixType(QualType QT,const LangOptions & LangOpt,ASTContext & Ctx,bool IsObjCLiteral)643 bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
644 ASTContext &Ctx, bool IsObjCLiteral) {
645 // %n is different from other conversion specifiers; don't try to fix it.
646 if (CS.getKind() == ConversionSpecifier::nArg)
647 return false;
648
649 // Handle Objective-C objects first. Note that while the '%@' specifier will
650 // not warn for structure pointer or void pointer arguments (because that's
651 // how CoreFoundation objects are implemented), we only show a fixit for '%@'
652 // if we know it's an object (block, id, class, or __attribute__((NSObject))).
653 if (QT->isObjCRetainableType()) {
654 if (!IsObjCLiteral)
655 return false;
656
657 CS.setKind(ConversionSpecifier::ObjCObjArg);
658
659 // Disable irrelevant flags
660 HasThousandsGrouping = false;
661 HasPlusPrefix = false;
662 HasSpacePrefix = false;
663 HasAlternativeForm = false;
664 HasLeadingZeroes = false;
665 Precision.setHowSpecified(OptionalAmount::NotSpecified);
666 LM.setKind(LengthModifier::None);
667
668 return true;
669 }
670
671 // Handle strings next (char *, wchar_t *)
672 if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
673 CS.setKind(ConversionSpecifier::sArg);
674
675 // Disable irrelevant flags
676 HasAlternativeForm = 0;
677 HasLeadingZeroes = 0;
678
679 // Set the long length modifier for wide characters
680 if (QT->getPointeeType()->isWideCharType())
681 LM.setKind(LengthModifier::AsWideChar);
682 else
683 LM.setKind(LengthModifier::None);
684
685 return true;
686 }
687
688 // If it's an enum, get its underlying type.
689 if (const EnumType *ETy = QT->getAs<EnumType>())
690 QT = ETy->getDecl()->getIntegerType();
691
692 const BuiltinType *BT = QT->getAs<BuiltinType>();
693 if (!BT) {
694 const VectorType *VT = QT->getAs<VectorType>();
695 if (VT) {
696 QT = VT->getElementType();
697 BT = QT->getAs<BuiltinType>();
698 VectorNumElts = OptionalAmount(VT->getNumElements());
699 }
700 }
701
702 // We can only work with builtin types.
703 if (!BT)
704 return false;
705
706 // Set length modifier
707 switch (BT->getKind()) {
708 case BuiltinType::Bool:
709 case BuiltinType::WChar_U:
710 case BuiltinType::WChar_S:
711 case BuiltinType::Char8: // FIXME: Treat like 'char'?
712 case BuiltinType::Char16:
713 case BuiltinType::Char32:
714 case BuiltinType::UInt128:
715 case BuiltinType::Int128:
716 case BuiltinType::Half:
717 case BuiltinType::Float16:
718 case BuiltinType::Float128:
719 case BuiltinType::ShortAccum:
720 case BuiltinType::Accum:
721 case BuiltinType::LongAccum:
722 case BuiltinType::UShortAccum:
723 case BuiltinType::UAccum:
724 case BuiltinType::ULongAccum:
725 case BuiltinType::ShortFract:
726 case BuiltinType::Fract:
727 case BuiltinType::LongFract:
728 case BuiltinType::UShortFract:
729 case BuiltinType::UFract:
730 case BuiltinType::ULongFract:
731 case BuiltinType::SatShortAccum:
732 case BuiltinType::SatAccum:
733 case BuiltinType::SatLongAccum:
734 case BuiltinType::SatUShortAccum:
735 case BuiltinType::SatUAccum:
736 case BuiltinType::SatULongAccum:
737 case BuiltinType::SatShortFract:
738 case BuiltinType::SatFract:
739 case BuiltinType::SatLongFract:
740 case BuiltinType::SatUShortFract:
741 case BuiltinType::SatUFract:
742 case BuiltinType::SatULongFract:
743 // Various types which are non-trivial to correct.
744 return false;
745
746 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
747 case BuiltinType::Id:
748 #include "clang/Basic/OpenCLImageTypes.def"
749 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
750 case BuiltinType::Id:
751 #include "clang/Basic/OpenCLExtensionTypes.def"
752 #define SIGNED_TYPE(Id, SingletonId)
753 #define UNSIGNED_TYPE(Id, SingletonId)
754 #define FLOATING_TYPE(Id, SingletonId)
755 #define BUILTIN_TYPE(Id, SingletonId) \
756 case BuiltinType::Id:
757 #include "clang/AST/BuiltinTypes.def"
758 // Misc other stuff which doesn't make sense here.
759 return false;
760
761 case BuiltinType::UInt:
762 case BuiltinType::Int:
763 case BuiltinType::Float:
764 case BuiltinType::Double:
765 LM.setKind(LengthModifier::None);
766 break;
767
768 case BuiltinType::Char_U:
769 case BuiltinType::UChar:
770 case BuiltinType::Char_S:
771 case BuiltinType::SChar:
772 LM.setKind(LengthModifier::AsChar);
773 break;
774
775 case BuiltinType::Short:
776 case BuiltinType::UShort:
777 LM.setKind(LengthModifier::AsShort);
778 break;
779
780 case BuiltinType::Long:
781 case BuiltinType::ULong:
782 LM.setKind(LengthModifier::AsLong);
783 break;
784
785 case BuiltinType::LongLong:
786 case BuiltinType::ULongLong:
787 LM.setKind(LengthModifier::AsLongLong);
788 break;
789
790 case BuiltinType::LongDouble:
791 LM.setKind(LengthModifier::AsLongDouble);
792 break;
793 }
794
795 // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99.
796 if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus11))
797 namedTypeToLengthModifier(QT, LM);
798
799 // If fixing the length modifier was enough, we might be done.
800 if (hasValidLengthModifier(Ctx.getTargetInfo())) {
801 // If we're going to offer a fix anyway, make sure the sign matches.
802 switch (CS.getKind()) {
803 case ConversionSpecifier::uArg:
804 case ConversionSpecifier::UArg:
805 if (QT->isSignedIntegerType())
806 CS.setKind(clang::analyze_format_string::ConversionSpecifier::dArg);
807 break;
808 case ConversionSpecifier::dArg:
809 case ConversionSpecifier::DArg:
810 case ConversionSpecifier::iArg:
811 if (QT->isUnsignedIntegerType() && !HasPlusPrefix)
812 CS.setKind(clang::analyze_format_string::ConversionSpecifier::uArg);
813 break;
814 default:
815 // Other specifiers do not have signed/unsigned variants.
816 break;
817 }
818
819 const analyze_printf::ArgType &ATR = getArgType(Ctx, IsObjCLiteral);
820 if (ATR.isValid() && ATR.matchesType(Ctx, QT))
821 return true;
822 }
823
824 // Set conversion specifier and disable any flags which do not apply to it.
825 // Let typedefs to char fall through to int, as %c is silly for uint8_t.
826 if (!isa<TypedefType>(QT) && QT->isCharType()) {
827 CS.setKind(ConversionSpecifier::cArg);
828 LM.setKind(LengthModifier::None);
829 Precision.setHowSpecified(OptionalAmount::NotSpecified);
830 HasAlternativeForm = 0;
831 HasLeadingZeroes = 0;
832 HasPlusPrefix = 0;
833 }
834 // Test for Floating type first as LongDouble can pass isUnsignedIntegerType
835 else if (QT->isRealFloatingType()) {
836 CS.setKind(ConversionSpecifier::fArg);
837 }
838 else if (QT->isSignedIntegerType()) {
839 CS.setKind(ConversionSpecifier::dArg);
840 HasAlternativeForm = 0;
841 }
842 else if (QT->isUnsignedIntegerType()) {
843 CS.setKind(ConversionSpecifier::uArg);
844 HasAlternativeForm = 0;
845 HasPlusPrefix = 0;
846 } else {
847 llvm_unreachable("Unexpected type");
848 }
849
850 return true;
851 }
852
toString(raw_ostream & os) const853 void PrintfSpecifier::toString(raw_ostream &os) const {
854 // Whilst some features have no defined order, we are using the order
855 // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1)
856 os << "%";
857
858 // Positional args
859 if (usesPositionalArg()) {
860 os << getPositionalArgIndex() << "$";
861 }
862
863 // Conversion flags
864 if (IsLeftJustified) os << "-";
865 if (HasPlusPrefix) os << "+";
866 if (HasSpacePrefix) os << " ";
867 if (HasAlternativeForm) os << "#";
868 if (HasLeadingZeroes) os << "0";
869
870 // Minimum field width
871 FieldWidth.toString(os);
872 // Precision
873 Precision.toString(os);
874
875 // Vector modifier
876 if (!VectorNumElts.isInvalid())
877 os << 'v' << VectorNumElts.getConstantAmount();
878
879 // Length modifier
880 os << LM.toString();
881 // Conversion specifier
882 os << CS.toString();
883 }
884
hasValidPlusPrefix() const885 bool PrintfSpecifier::hasValidPlusPrefix() const {
886 if (!HasPlusPrefix)
887 return true;
888
889 // The plus prefix only makes sense for signed conversions
890 switch (CS.getKind()) {
891 case ConversionSpecifier::dArg:
892 case ConversionSpecifier::DArg:
893 case ConversionSpecifier::iArg:
894 case ConversionSpecifier::fArg:
895 case ConversionSpecifier::FArg:
896 case ConversionSpecifier::eArg:
897 case ConversionSpecifier::EArg:
898 case ConversionSpecifier::gArg:
899 case ConversionSpecifier::GArg:
900 case ConversionSpecifier::aArg:
901 case ConversionSpecifier::AArg:
902 case ConversionSpecifier::FreeBSDrArg:
903 case ConversionSpecifier::FreeBSDyArg:
904 return true;
905
906 default:
907 return false;
908 }
909 }
910
hasValidAlternativeForm() const911 bool PrintfSpecifier::hasValidAlternativeForm() const {
912 if (!HasAlternativeForm)
913 return true;
914
915 // Alternate form flag only valid with the oxXaAeEfFgG conversions
916 switch (CS.getKind()) {
917 case ConversionSpecifier::oArg:
918 case ConversionSpecifier::OArg:
919 case ConversionSpecifier::xArg:
920 case ConversionSpecifier::XArg:
921 case ConversionSpecifier::aArg:
922 case ConversionSpecifier::AArg:
923 case ConversionSpecifier::eArg:
924 case ConversionSpecifier::EArg:
925 case ConversionSpecifier::fArg:
926 case ConversionSpecifier::FArg:
927 case ConversionSpecifier::gArg:
928 case ConversionSpecifier::GArg:
929 case ConversionSpecifier::FreeBSDrArg:
930 case ConversionSpecifier::FreeBSDyArg:
931 return true;
932
933 default:
934 return false;
935 }
936 }
937
hasValidLeadingZeros() const938 bool PrintfSpecifier::hasValidLeadingZeros() const {
939 if (!HasLeadingZeroes)
940 return true;
941
942 // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions
943 switch (CS.getKind()) {
944 case ConversionSpecifier::dArg:
945 case ConversionSpecifier::DArg:
946 case ConversionSpecifier::iArg:
947 case ConversionSpecifier::oArg:
948 case ConversionSpecifier::OArg:
949 case ConversionSpecifier::uArg:
950 case ConversionSpecifier::UArg:
951 case ConversionSpecifier::xArg:
952 case ConversionSpecifier::XArg:
953 case ConversionSpecifier::aArg:
954 case ConversionSpecifier::AArg:
955 case ConversionSpecifier::eArg:
956 case ConversionSpecifier::EArg:
957 case ConversionSpecifier::fArg:
958 case ConversionSpecifier::FArg:
959 case ConversionSpecifier::gArg:
960 case ConversionSpecifier::GArg:
961 case ConversionSpecifier::FreeBSDrArg:
962 case ConversionSpecifier::FreeBSDyArg:
963 return true;
964
965 default:
966 return false;
967 }
968 }
969
hasValidSpacePrefix() const970 bool PrintfSpecifier::hasValidSpacePrefix() const {
971 if (!HasSpacePrefix)
972 return true;
973
974 // The space prefix only makes sense for signed conversions
975 switch (CS.getKind()) {
976 case ConversionSpecifier::dArg:
977 case ConversionSpecifier::DArg:
978 case ConversionSpecifier::iArg:
979 case ConversionSpecifier::fArg:
980 case ConversionSpecifier::FArg:
981 case ConversionSpecifier::eArg:
982 case ConversionSpecifier::EArg:
983 case ConversionSpecifier::gArg:
984 case ConversionSpecifier::GArg:
985 case ConversionSpecifier::aArg:
986 case ConversionSpecifier::AArg:
987 case ConversionSpecifier::FreeBSDrArg:
988 case ConversionSpecifier::FreeBSDyArg:
989 return true;
990
991 default:
992 return false;
993 }
994 }
995
hasValidLeftJustified() const996 bool PrintfSpecifier::hasValidLeftJustified() const {
997 if (!IsLeftJustified)
998 return true;
999
1000 // The left justified flag is valid for all conversions except n
1001 switch (CS.getKind()) {
1002 case ConversionSpecifier::nArg:
1003 return false;
1004
1005 default:
1006 return true;
1007 }
1008 }
1009
hasValidThousandsGroupingPrefix() const1010 bool PrintfSpecifier::hasValidThousandsGroupingPrefix() const {
1011 if (!HasThousandsGrouping)
1012 return true;
1013
1014 switch (CS.getKind()) {
1015 case ConversionSpecifier::dArg:
1016 case ConversionSpecifier::DArg:
1017 case ConversionSpecifier::iArg:
1018 case ConversionSpecifier::uArg:
1019 case ConversionSpecifier::UArg:
1020 case ConversionSpecifier::fArg:
1021 case ConversionSpecifier::FArg:
1022 case ConversionSpecifier::gArg:
1023 case ConversionSpecifier::GArg:
1024 return true;
1025 default:
1026 return false;
1027 }
1028 }
1029
hasValidPrecision() const1030 bool PrintfSpecifier::hasValidPrecision() const {
1031 if (Precision.getHowSpecified() == OptionalAmount::NotSpecified)
1032 return true;
1033
1034 // Precision is only valid with the diouxXaAeEfFgGsP conversions
1035 switch (CS.getKind()) {
1036 case ConversionSpecifier::dArg:
1037 case ConversionSpecifier::DArg:
1038 case ConversionSpecifier::iArg:
1039 case ConversionSpecifier::oArg:
1040 case ConversionSpecifier::OArg:
1041 case ConversionSpecifier::uArg:
1042 case ConversionSpecifier::UArg:
1043 case ConversionSpecifier::xArg:
1044 case ConversionSpecifier::XArg:
1045 case ConversionSpecifier::aArg:
1046 case ConversionSpecifier::AArg:
1047 case ConversionSpecifier::eArg:
1048 case ConversionSpecifier::EArg:
1049 case ConversionSpecifier::fArg:
1050 case ConversionSpecifier::FArg:
1051 case ConversionSpecifier::gArg:
1052 case ConversionSpecifier::GArg:
1053 case ConversionSpecifier::sArg:
1054 case ConversionSpecifier::FreeBSDrArg:
1055 case ConversionSpecifier::FreeBSDyArg:
1056 case ConversionSpecifier::PArg:
1057 return true;
1058
1059 default:
1060 return false;
1061 }
1062 }
hasValidFieldWidth() const1063 bool PrintfSpecifier::hasValidFieldWidth() const {
1064 if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified)
1065 return true;
1066
1067 // The field width is valid for all conversions except n
1068 switch (CS.getKind()) {
1069 case ConversionSpecifier::nArg:
1070 return false;
1071
1072 default:
1073 return true;
1074 }
1075 }
1076