clang 8.0.0

PrintfFormatString.cpp
Go to the documentation of this file.
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
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
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
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
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
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
467 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
629 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
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
853 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
885 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
911 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
938 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
970 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
996 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
1010 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
1030 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 }
1063 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 }
clang::analyze_format_string::ConversionSpecifier::FreeBSDyArg
Definition: FormatString.h:178
clang::CanQual::withConst
QualType withConst() const
Retrieves a version of this type with const applied.
Definition: CanonicalType.h:162
clang::ASTContext::LongLongTy
CanQualType LongLongTy
Definition: ASTContext.h:1025
clang::analyze_format_string::ArgType::WCStrTy
Definition: FormatString.h:252
clang::analyze_format_string::ArgType::makePtrdiffT
static ArgType makePtrdiffT(const ArgType &A)
Create an ArgType which corresponds to the ptrdiff_t/unsigned ptrdiff_t type.
Definition: FormatString.h:296
clang::analyze_format_string::SpecifierResult::hasValue
bool hasValue() const
Definition: FormatStringParsing.h:72
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:638
clang::analyze_format_string::ConversionSpecifier::XArg
Definition: FormatString.h:138
clang::analyze_format_string::SpecifierResult::getStart
const char * getStart() const
Definition: FormatStringParsing.h:70
clang::analyze_printf::PrintfSpecifier::setIsPublic
void setIsPublic(const char *position)
Definition: FormatString.h:537
clang::ASTContext::getPointerDiffType
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
Definition: ASTContext.cpp:5002
clang::BuiltinType::getKind
Kind getKind() const
Definition: Type.h:2418
clang::Type::getPointeeType
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Definition: Type.cpp:505
clang::TargetInfo::getTriple
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Definition: TargetInfo.h:953
clang::analyze_format_string::ConversionSpecifier::ZArg
Definition: FormatString.h:167
clang::Type::isRealFloatingType
bool isRealFloatingType() const
Floating point categories.
Definition: Type.cpp:1937
clang::analyze_format_string::ParseVectorModifier
bool ParseVectorModifier(FormatStringHandler &H, FormatSpecifier &FS, const char *&Beg, const char *E, const LangOptions &LO)
Definition: FormatString.cpp:182
clang::analyze_format_string::ConversionSpecifier::FreeBSDbArg
Definition: FormatString.h:175
clang::analyze_format_string::ConversionSpecifier::SArg
Definition: FormatString.h:158
clang::analyze_format_string::FormatStringHandler::HandleInvalidObjCModifierFlag
virtual void HandleInvalidObjCModifierFlag(const char *startFlag, unsigned flagLen)
Definition: FormatString.h:697
ParseObjCFlags
static bool ParseObjCFlags(FormatStringHandler &H, PrintfSpecifier &FS, const char *FlagBeg, const char *E, bool Warn)
Definition: PrintfFormatString.cpp:53
ParsePrecision
static bool ParsePrecision(FormatStringHandler &H, PrintfSpecifier &FS, const char *Start, const char *&Beg, const char *E, unsigned *argIndex)
Definition: PrintfFormatString.cpp:38
clang::analyze_format_string::ParseArgPosition
bool ParseArgPosition(FormatStringHandler &H, FormatSpecifier &CS, const char *Start, const char *&Beg, const char *E)
Definition: FormatString.cpp:145
clang::ASTContext::LongTy
CanQualType LongTy
Definition: ASTContext.h:1025
clang::analyze_format_string::ConversionSpecifier::DArg
Definition: FormatString.h:128
clang::ASTContext::getTargetInfo
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:690
clang::analyze_format_string::ConversionSpecifier::xArg
Definition: FormatString.h:137
clang::analyze_printf::PrintfSpecifier::setHasLeadingZeros
void setHasLeadingZeros(const char *position)
Definition: FormatString.h:530
clang::ASTContext::WideCharTy
CanQualType WideCharTy
Definition: ASTContext.h:1020
clang::analyze_printf::PrintfSpecifier::usesPositionalArg
bool usesPositionalArg() const
Definition: FormatString.h:581
clang::analyze_format_string::LengthModifier::AsInt64
Definition: FormatString.h:79
clang::Type::isUnsignedIntegerType
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
Definition: Type.cpp:1884
clang::Type::getAs
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6748
clang::analyze_format_string::ConversionSpecifier::consumesDataArgument
bool consumesDataArgument() const
Definition: FormatString.h:207
clang::analyze_format_string::ArgType::CPointerTy
Definition: FormatString.h:251
clang::analyze_format_string::FormatStringHandler::HandleEmptyObjCModifierFlag
virtual void HandleEmptyObjCModifierFlag(const char *startFlags, unsigned flagsLen)
Definition: FormatString.h:694
clang::Type::isWideCharType
bool isWideCharType() const
Definition: Type.cpp:1796
clang::analyze_printf::PrintfSpecifier::setPrecision
void setPrecision(const OptionalAmount &Amt)
Definition: FormatString.h:549
clang::analyze_format_string::ArgType::makeSizeT
static ArgType makeSizeT(const ArgType &A)
Create an ArgType which corresponds to the size_t/ssize_t type.
Definition: FormatString.h:288
clang::analyze_format_string::LengthModifier::AsLong
Definition: FormatString.h:71
clang::analyze_format_string::ConversionSpecifier::InvalidSpecifier
Definition: FormatString.h:124
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:155
clang::analyze_printf
Pieces specific to fprintf format strings.
Definition: FormatString.h:460
clang::analyze_format_string::ArgType
Definition: FormatString.h:249
toString
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Definition: SanitizerArgs.cpp:775
clang::Type::isCharType
bool isCharType() const
Definition: Type.cpp:1787
clang::analyze_format_string::ArgType::WIntTy
Definition: FormatString.h:252
clang::analyze_printf::PrintfSpecifier::setHasSpacePrefix
void setHasSpacePrefix(const char *position)
Definition: FormatString.h:524
clang::analyze_format_string::ConversionSpecifier
Definition: FormatString.h:121
clang::analyze_format_string::LengthModifier::AsLongDouble
Definition: FormatString.h:80
clang::analyze_format_string::ArgType::AnyCharTy
Definition: FormatString.h:252
clang::analyze_format_string::LengthModifier::AsMAllocate
Definition: FormatString.h:82
clang::LangOptions
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:50
clang::ASTContext::getUnsignedPointerDiffType
QualType getUnsignedPointerDiffType() const
Return the unique unsigned counterpart of "ptrdiff_t" integer type.
Definition: ASTContext.cpp:5009
clang::analyze_printf::PrintfSpecifier::setConversionSpecifier
void setConversionSpecifier(const PrintfConversionSpecifier &cs)
Definition: FormatString.h:512
clang::analyze_format_string::FormatStringHandler::HandleInvalidPrintfConversionSpecifier
virtual bool HandleInvalidPrintfConversionSpecifier(const analyze_printf::PrintfSpecifier &FS, const char *startSpecifier, unsigned specifierLen)
Definition: FormatString.h:705
clang::analyze_format_string::LengthModifier::AsWide
Definition: FormatString.h:83
clang::analyze_format_string::ArgType::matchesType
MatchKind matchesType(ASTContext &C, QualType argTy) const
Definition: FormatString.cpp:322
clang::analyze_format_string::ConversionSpecifier::AArg
Definition: FormatString.h:149
clang::analyze_format_string::ConversionSpecifier::CArg
Definition: FormatString.h:157
clang::analyze_format_string::LengthModifier::AsLongLong
Definition: FormatString.h:72
clang::analyze_format_string::PrecisionPos
Definition: FormatString.h:675
clang::analyze_format_string::LengthModifier::AsWideChar
Definition: FormatString.h:84
clang::analyze_format_string::LengthModifier
Represents the length modifier in a format string in scanf/printf.
Definition: FormatString.h:65
clang::analyze_format_string::ConversionSpecifier::cArg
Definition: FormatString.h:126
clang::analyze_format_string::LengthModifier::AsQuad
Definition: FormatString.h:73
clang::analyze_format_string::ConversionSpecifier::FArg
Definition: FormatString.h:143
clang::ASTContext::LongDoubleTy
CanQualType LongDoubleTy
Definition: ASTContext.h:1028
clang::analyze_format_string::ConversionSpecifier::FreeBSDrArg
Definition: FormatString.h:177
clang::analyze_format_string::LengthModifier::AsInt3264
Definition: FormatString.h:78
clang::analyze_printf::PrintfSpecifier::setIsLeftJustified
void setIsLeftJustified(const char *position)
Definition: FormatString.h:518
clang::analyze_format_string::LengthModifier::AsInt32
Definition: FormatString.h:77
clang::analyze_format_string::FormatStringHandler::handleInvalidMaskType
virtual void handleInvalidMaskType(StringRef MaskType)
Handle mask types whose sizes are not between one and eight bytes.
Definition: FormatString.h:719
clang::ASTContext::UnsignedCharTy
CanQualType UnsignedCharTy
Definition: ASTContext.h:1026
clang::analyze_format_string::ArgType::PtrTo
static ArgType PtrTo(const ArgType &A)
Create an ArgType which corresponds to the type pointer to A.
Definition: FormatString.h:280
clang::analyze_format_string::ParseNonPositionAmount
OptionalAmount ParseNonPositionAmount(const char *&Beg, const char *E, unsigned &argIndex)
Definition: FormatString.cpp:64
clang::analyze_os_log::OSLogBufferItem::IsSensitive
Definition: OSLog.h:69
clang::analyze_format_string::ConversionSpecifier::fArg
Definition: FormatString.h:142
clang::analyze_format_string::LengthModifier::AsSizeT
Definition: FormatString.h:75
clang::analyze_format_string::ConversionSpecifier::nArg
Definition: FormatString.h:155
clang::analyze_format_string::ConversionSpecifier::PrintErrno
Definition: FormatString.h:181
clang::analyze_format_string::LengthModifier::None
Definition: FormatString.h:68
clang::analyze_format_string::ConversionSpecifier::Kind
Kind
Definition: FormatString.h:123
clang::analyze_format_string::ArgType::makeVectorType
ArgType makeVectorType(ASTContext &C, unsigned NumElts) const
Definition: FormatString.cpp:490
clang::TargetInfo
Exposes information about the current target.
Definition: TargetInfo.h:54
clang::analyze_format_string::ConversionSpecifier::pArg
Definition: FormatString.h:154
clang::Type::isObjCRetainableType
bool isObjCRetainableType() const
Definition: Type.cpp:3921
clang::analyze_format_string::ConversionSpecifier::PArg
Definition: FormatString.h:163
clang::analyze_format_string::ConversionSpecifier::ObjCObjArg
Definition: FormatString.h:170
clang::analyze_format_string::ConversionSpecifier::EArg
Definition: FormatString.h:145
clang::ASTContext::ShortTy
CanQualType ShortTy
Definition: ASTContext.h:1025
clang::analyze_format_string::ArgType::Invalid
static ArgType Invalid()
Definition: FormatString.h:272
clang::Type::isSignedIntegerType
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char, signed char, short, int, long..], or an enum decl which has a signed representation.
Definition: Type.cpp:1844
clang::analyze_format_string::FormatStringHandler::HandleNullChar
virtual void HandleNullChar(const char *nullCharacter)
Definition: FormatString.h:682
clang::analyze_format_string::FormatStringHandler
Definition: FormatString.h:677
clang::analyze_printf::PrintfConversionSpecifier
Definition: FormatString.h:462
clang::analyze_format_string::OptionalAmount
Definition: FormatString.h:311
clang::VectorType
Represents a GCC generic vector type.
Definition: Type.h:3168
clang::analyze_format_string::SpecifierResult::getValue
const T & getValue() const
Definition: FormatStringParsing.h:73
clang::analyze_format_string::ConversionSpecifier::sArg
Definition: FormatString.h:153
clang::analyze_format_string::ConversionSpecifier::OArg
Definition: FormatString.h:134
clang::ASTContext::SignedCharTy
CanQualType SignedCharTy
Definition: ASTContext.h:1025
clang::analyze_format_string::ConversionSpecifier::uArg
Definition: FormatString.h:135
clang::ASTContext::getUIntMaxType
CanQualType getUIntMaxType() const
Return the unique type for "uintmax_t" (C99 7.18.1.5), defined in <stdint.h>.
Definition: ASTContext.cpp:4974
clang::analyze_format_string::OptionalAmount::NotSpecified
Definition: FormatString.h:313
clang::analyze_format_string::ParseFormatStringHasSArg
bool ParseFormatStringHasSArg(const char *beg, const char *end, const LangOptions &LO, const TargetInfo &Target)
Definition: PrintfFormatString.cpp:434
clang::analyze_format_string::FormatStringHandler::HandleObjCFlagsWithNonObjCConversion
virtual void HandleObjCFlagsWithNonObjCConversion(const char *flagsStart, const char *flagsEnd, const char *conversionPosition)
Definition: FormatString.h:700
clang::EnumType
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
Definition: Type.h:4396
clang::analyze_format_string::ArgType::CStrTy
Definition: FormatString.h:252
clang::analyze_format_string::OptionalAmount::isInvalid
bool isInvalid() const
Definition: FormatString.h:331
clang::analyze_printf::PrintfSpecifier::setMaskType
void setMaskType(StringRef S)
Definition: FormatString.h:584
clang::analyze_format_string::LengthModifier::AsAllocate
Definition: FormatString.h:81
clang::analyze_printf::PrintfSpecifier::setIsPrivate
void setIsPrivate(const char *position)
Definition: FormatString.h:536
clang::VectorType::getElementType
QualType getElementType() const
Definition: Type.h:3203
clang::analyze_format_string::LengthModifier::AsChar
Definition: FormatString.h:69
clang::ASTContext::getSignedSizeType
CanQualType getSignedSizeType() const
Return the unique signed counterpart of the integer type corresponding to size_t. ...
Definition: ASTContext.cpp:4964
llvm::SmallVector
Definition: LLVM.h:36
clang::analyze_printf::PrintfSpecifier::setHasThousandsGrouping
void setHasThousandsGrouping(const char *position)
Definition: FormatString.h:515
clang::analyze_format_string::ArgType::isValid
bool isValid() const
Definition: FormatString.h:273
clang::analyze_os_log::OSLogBufferItem::IsPublic
Definition: OSLog.h:66
clang::Type::isAnyCharacterType
bool isAnyCharacterType() const
Determine whether this type is any of the built-in character types.
Definition: Type.cpp:1823
clang::analyze_format_string::ConversionSpecifier::oArg
Definition: FormatString.h:133
clang::analyze_format_string::ConversionSpecifier::GArg
Definition: FormatString.h:147
clang::analyze_printf::PrintfSpecifier
Definition: FormatString.h:485
clang::analyze_format_string::ParseFieldWidth
bool ParseFieldWidth(FormatStringHandler &H, FormatSpecifier &CS, const char *Start, const char *&Beg, const char *E, unsigned *argIndex)
Definition: FormatString.cpp:123
FormatString.h
clang::analyze_printf::PrintfSpecifier::getConversionSpecifier
const PrintfConversionSpecifier & getConversionSpecifier() const
Definition: FormatString.h:545
clang::analyze_format_string::FormatStringHandler::HandlePrintfSpecifier
virtual bool HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier &FS, const char *startSpecifier, unsigned specifierLen)
Definition: FormatString.h:712
clang::ASTContext::UnsignedShortTy
CanQualType UnsignedShortTy
Definition: ASTContext.h:1026
clang::analyze_format_string::ConversionSpecifier::aArg
Definition: FormatString.h:148
clang
Dataflow Directional Tag Classes.
Definition: CFGReachabilityAnalysis.h:22
clang::analyze_format_string::ConversionSpecifier::getKind
Kind getKind() const
Definition: FormatString.h:221
clang::analyze_format_string::ConversionSpecifier::iArg
Definition: FormatString.h:129
clang::analyze_format_string::ConversionSpecifier::FreeBSDDArg
Definition: FormatString.h:176
clang::ASTContext::UnsignedLongLongTy
CanQualType UnsignedLongLongTy
Definition: ASTContext.h:1027
clang::analyze_format_string::ConversionSpecifier::PercentArg
Definition: FormatString.h:156
clang::analyze_format_string::ArgType::ObjCPointerTy
Definition: FormatString.h:251
clang::analyze_format_string::FormatSpecifier::setArgIndex
void setArgIndex(unsigned i)
Definition: FormatString.h:406
clang::analyze_format_string::LengthModifier::AsPtrDiff
Definition: FormatString.h:76
clang::analyze_format_string::ParseUTF8InvalidSpecifier
bool ParseUTF8InvalidSpecifier(const char *SpecifierBegin, const char *FmtStrEnd, unsigned &Len)
Returns true if the invalid specifier in SpecifierBegin is a UTF-8 string; check that it won&#39;t go fur...
Definition: FormatString.cpp:294
OSLog.h
clang::analyze_format_string
Common components of both fprintf and fscanf format strings.
Definition: FormatString.h:30
clang::analyze_format_string::ConversionSpecifier::UArg
Definition: FormatString.h:136
clang::analyze_printf::PrintfSpecifier::setHasObjCTechnicalTerm
void setHasObjCTechnicalTerm(const char *position)
Definition: FormatString.h:533
clang::ASTContext::UnsignedLongTy
CanQualType UnsignedLongTy
Definition: ASTContext.h:1026
clang::analyze_os_log::OSLogBufferItem::IsPrivate
Definition: OSLog.h:63
clang::analyze_format_string::ParseLengthModifier
bool ParseLengthModifier(FormatSpecifier &FS, const char *&Beg, const char *E, const LangOptions &LO, bool IsScanf=false)
Returns true if a LengthModifier was parsed and installed in the FormatSpecifier& argument...
Definition: FormatString.cpp:212
clang::analyze_printf::PrintfSpecifier::setHasPlusPrefix
void setHasPlusPrefix(const char *position)
Definition: FormatString.h:521
clang::analyze_format_string::LengthModifier::AsShort
Definition: FormatString.h:70
clang::analyze_format_string::LengthModifier::AsIntMax
Definition: FormatString.h:74
clang::analyze_format_string::ConversionSpecifier::eArg
Definition: FormatString.h:144
clang::analyze_format_string::ConversionSpecifier::gArg
Definition: FormatString.h:146
clang::analyze_format_string::FormatStringHandler::HandleIncompleteSpecifier
virtual void HandleIncompleteSpecifier(const char *startSpecifier, unsigned specifierLen)
Definition: FormatString.h:691
clang::ASTContext::getPointerType
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
Definition: ASTContext.cpp:2847
clang::BuiltinType
This class is used for builtin types like &#39;int&#39;.
Definition: Type.h:2391
clang::analyze_format_string::ConversionSpecifier::setEndScanList
void setEndScanList(const char *pos)
Definition: FormatString.h:226
TargetInfo.h
Defines the clang::TargetInfo interface.
FormatStringParsing.h
clang::analyze_format_string::SpecifierResult
Definition: FormatStringParsing.h:59
clang::ASTContext::IntTy
CanQualType IntTy
Definition: ASTContext.h:1025
clang::VectorType::getNumElements
unsigned getNumElements() const
Definition: Type.h:3204
clang::analyze_format_string::ConversionSpecifier::dArg
Definition: FormatString.h:127
clang::analyze_format_string::ParsePrintfString
bool ParsePrintfString(FormatStringHandler &H, const char *beg, const char *end, const LangOptions &LO, const TargetInfo &Target, bool isFreeBSDKPrintf)
Definition: PrintfFormatString.cpp:403
clang::Type::isPointerType
bool isPointerType() const
Definition: Type.h:6296
clang::analyze_printf::PrintfSpecifier::setHasAlternativeForm
void setHasAlternativeForm(const char *position)
Definition: FormatString.h:527
clang::analyze_printf::PrintfSpecifier::setIsSensitive
void setIsSensitive(const char *position)
Definition: FormatString.h:538
clang::analyze_format_string::SpecifierResult::shouldStop
bool shouldStop() const
Definition: FormatStringParsing.h:71
PrintfSpecifierResult
clang::analyze_format_string::SpecifierResult< PrintfSpecifier > PrintfSpecifierResult
Definition: PrintfFormatString.cpp:30
clang::ASTContext::getIntMaxType
CanQualType getIntMaxType() const
Return the unique type for "intmax_t" (C99 7.18.1.5), defined in <stdint.h>.
Definition: ASTContext.cpp:4969
clang::ASTContext::DoubleTy
CanQualType DoubleTy
Definition: ASTContext.h:1028
ParsePrintfSpecifier
static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, const char *&Beg, const char *E, unsigned &argIndex, const LangOptions &LO, const TargetInfo &Target, bool Warn, bool isFreeBSDKPrintf)
Definition: PrintfFormatString.cpp:71
clang::ASTContext::UnsignedIntTy
CanQualType UnsignedIntTy
Definition: ASTContext.h:1026
clang::analyze_format_string::ParsePositionAmount
OptionalAmount ParsePositionAmount(FormatStringHandler &H, const char *Start, const char *&Beg, const char *E, PositionContext p)
Definition: FormatString.cpp:76
clang::ASTContext::getSizeType
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
Definition: ASTContext.cpp:4958
clang::UpdateOnReturn
Definition: FormatStringParsing.h:13