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   // Look for the length modifier.
251   if (ParseLengthModifier(FS, I, E, LO) && I == E) {
252     // No more characters left?
253     if (Warn)
254       H.HandleIncompleteSpecifier(Start, E - Start);
255     return true;
256   }
257 
258   // Look for the Objective-C modifier flags, if any.
259   // We parse these here, even if they don't apply to
260   // the conversion specifier, and then emit an error
261   // later if the conversion specifier isn't '@'.  This
262   // enables better recovery, and we don't know if
263   // these flags are applicable until later.
264   const char *ObjCModifierFlagsStart = nullptr,
265              *ObjCModifierFlagsEnd = nullptr;
266   if (*I == '[') {
267     ObjCModifierFlagsStart = I;
268     ++I;
269     auto flagStart = I;
270     for (;; ++I) {
271       ObjCModifierFlagsEnd = I;
272       if (I == E) {
273         if (Warn)
274           H.HandleIncompleteSpecifier(Start, E - Start);
275         return true;
276       }
277       // Did we find the closing ']'?
278       if (*I == ']') {
279         if (ParseObjCFlags(H, FS, flagStart, I, Warn))
280           return true;
281         ++I;
282         break;
283       }
284       // There are no separators defined yet for multiple
285       // Objective-C modifier flags.  When those are
286       // defined, this is the place to check.
287     }
288   }
289 
290   if (*I == '\0') {
291     // Detect spurious null characters, which are likely errors.
292     H.HandleNullChar(I);
293     return true;
294   }
295 
296   // Finally, look for the conversion specifier.
297   const char *conversionPosition = I++;
298   ConversionSpecifier::Kind k = ConversionSpecifier::InvalidSpecifier;
299   switch (*conversionPosition) {
300     default:
301       break;
302     // C99: 7.19.6.1 (section 8).
303     case '%': k = ConversionSpecifier::PercentArg;   break;
304     case 'A': k = ConversionSpecifier::AArg; break;
305     case 'E': k = ConversionSpecifier::EArg; break;
306     case 'F': k = ConversionSpecifier::FArg; break;
307     case 'G': k = ConversionSpecifier::GArg; break;
308     case 'X': k = ConversionSpecifier::XArg; break;
309     case 'a': k = ConversionSpecifier::aArg; break;
310     case 'c': k = ConversionSpecifier::cArg; break;
311     case 'd': k = ConversionSpecifier::dArg; break;
312     case 'e': k = ConversionSpecifier::eArg; break;
313     case 'f': k = ConversionSpecifier::fArg; break;
314     case 'g': k = ConversionSpecifier::gArg; break;
315     case 'i': k = ConversionSpecifier::iArg; break;
316     case 'n': k = ConversionSpecifier::nArg; break;
317     case 'o': k = ConversionSpecifier::oArg; break;
318     case 'p': k = ConversionSpecifier::pArg; break;
319     case 's': k = ConversionSpecifier::sArg; break;
320     case 'u': k = ConversionSpecifier::uArg; break;
321     case 'x': k = ConversionSpecifier::xArg; break;
322     // POSIX specific.
323     case 'C': k = ConversionSpecifier::CArg; break;
324     case 'S': k = ConversionSpecifier::SArg; break;
325     // Apple extension for os_log
326     case 'P':
327       k = ConversionSpecifier::PArg;
328       break;
329     // Objective-C.
330     case '@': k = ConversionSpecifier::ObjCObjArg; break;
331     // Glibc specific.
332     case 'm': k = ConversionSpecifier::PrintErrno; break;
333     // FreeBSD kernel specific.
334     case 'b':
335       if (isFreeBSDKPrintf)
336         k = ConversionSpecifier::FreeBSDbArg; // int followed by char *
337       break;
338     case 'r':
339       if (isFreeBSDKPrintf)
340         k = ConversionSpecifier::FreeBSDrArg; // int
341       break;
342     case 'y':
343       if (isFreeBSDKPrintf)
344         k = ConversionSpecifier::FreeBSDyArg; // int
345       break;
346     // Apple-specific.
347     case 'D':
348       if (isFreeBSDKPrintf)
349         k = ConversionSpecifier::FreeBSDDArg; // void * followed by char *
350       else if (Target.getTriple().isOSDarwin())
351         k = ConversionSpecifier::DArg;
352       break;
353     case 'O':
354       if (Target.getTriple().isOSDarwin())
355         k = ConversionSpecifier::OArg;
356       break;
357     case 'U':
358       if (Target.getTriple().isOSDarwin())
359         k = ConversionSpecifier::UArg;
360       break;
361     // MS specific.
362     case 'Z':
363       if (Target.getTriple().isOSMSVCRT())
364         k = ConversionSpecifier::ZArg;
365       break;
366     // OpenCL specific.
367     case 'v':
368       if (LO.OpenCL)
369         k = ConversionSpecifier::VArg;
370       break;
371   }
372 
373   // Check to see if we used the Objective-C modifier flags with
374   // a conversion specifier other than '@'.
375   if (k != ConversionSpecifier::ObjCObjArg &&
376       k != ConversionSpecifier::InvalidSpecifier &&
377       ObjCModifierFlagsStart) {
378     H.HandleObjCFlagsWithNonObjCConversion(ObjCModifierFlagsStart,
379                                            ObjCModifierFlagsEnd + 1,
380                                            conversionPosition);
381     return true;
382   }
383 
384   PrintfConversionSpecifier CS(conversionPosition, k);
385   FS.setConversionSpecifier(CS);
386   if (CS.consumesDataArgument() && !FS.usesPositionalArg())
387     FS.setArgIndex(argIndex++);
388   // FreeBSD kernel specific.
389   if (k == ConversionSpecifier::FreeBSDbArg ||
390       k == ConversionSpecifier::FreeBSDDArg)
391     argIndex++;
392 
393   if (k == ConversionSpecifier::InvalidSpecifier) {
394     unsigned Len = I - Start;
395     if (ParseUTF8InvalidSpecifier(Start, E, Len)) {
396       CS.setEndScanList(Start + Len);
397       FS.setConversionSpecifier(CS);
398     }
399     // Assume the conversion takes one argument.
400     return !H.HandleInvalidPrintfConversionSpecifier(FS, Start, Len);
401   }
402   return PrintfSpecifierResult(Start, FS);
403 }
404 
405 bool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H,
406                                                      const char *I,
407                                                      const char *E,
408                                                      const LangOptions &LO,
409                                                      const TargetInfo &Target,
410                                                      bool isFreeBSDKPrintf) {
411 
412   unsigned argIndex = 0;
413 
414   // Keep looking for a format specifier until we have exhausted the string.
415   while (I != E) {
416     const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
417                                                             LO, Target, true,
418                                                             isFreeBSDKPrintf);
419     // Did a fail-stop error of any kind occur when parsing the specifier?
420     // If so, don't do any more processing.
421     if (FSR.shouldStop())
422       return true;
423     // Did we exhaust the string or encounter an error that
424     // we can recover from?
425     if (!FSR.hasValue())
426       continue;
427     // We have a format specifier.  Pass it to the callback.
428     if (!H.HandlePrintfSpecifier(FSR.getValue(), FSR.getStart(),
429                                  I - FSR.getStart()))
430       return true;
431   }
432   assert(I == E && "Format string not exhausted");
433   return false;
434 }
435 
436 bool clang::analyze_format_string::ParseFormatStringHasSArg(const char *I,
437                                                             const char *E,
438                                                             const LangOptions &LO,
439                                                             const TargetInfo &Target) {
440 
441   unsigned argIndex = 0;
442 
443   // Keep looking for a %s format specifier until we have exhausted the string.
444   FormatStringHandler H;
445   while (I != E) {
446     const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
447                                                             LO, Target, false,
448                                                             false);
449     // Did a fail-stop error of any kind occur when parsing the specifier?
450     // If so, don't do any more processing.
451     if (FSR.shouldStop())
452       return false;
453     // Did we exhaust the string or encounter an error that
454     // we can recover from?
455     if (!FSR.hasValue())
456       continue;
457     const analyze_printf::PrintfSpecifier &FS = FSR.getValue();
458     // Return true if this a %s format specifier.
459     if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::Kind::sArg)
460       return true;
461   }
462   return false;
463 }
464 
465 //===----------------------------------------------------------------------===//
466 // Methods on PrintfSpecifier.
467 //===----------------------------------------------------------------------===//
468 
469 ArgType PrintfSpecifier::getArgType(ASTContext &Ctx,
470                                     bool IsObjCLiteral) const {
471   const PrintfConversionSpecifier &CS = getConversionSpecifier();
472 
473   if (!CS.consumesDataArgument())
474     return ArgType::Invalid();
475 
476   if (CS.getKind() == ConversionSpecifier::cArg)
477     switch (LM.getKind()) {
478       case LengthModifier::None:
479         return Ctx.IntTy;
480       case LengthModifier::AsLong:
481       case LengthModifier::AsWide:
482         return ArgType(ArgType::WIntTy, "wint_t");
483       case LengthModifier::AsShort:
484         if (Ctx.getTargetInfo().getTriple().isOSMSVCRT())
485           return Ctx.IntTy;
486         LLVM_FALLTHROUGH;
487       default:
488         return ArgType::Invalid();
489     }
490 
491   if (CS.isIntArg())
492     switch (LM.getKind()) {
493       case LengthModifier::AsLongDouble:
494         // GNU extension.
495         return Ctx.LongLongTy;
496       case LengthModifier::None:
497         return Ctx.IntTy;
498       case LengthModifier::AsInt32:
499         return ArgType(Ctx.IntTy, "__int32");
500       case LengthModifier::AsChar: return ArgType::AnyCharTy;
501       case LengthModifier::AsShort: return Ctx.ShortTy;
502       case LengthModifier::AsLong: return Ctx.LongTy;
503       case LengthModifier::AsLongLong:
504       case LengthModifier::AsQuad:
505         return Ctx.LongLongTy;
506       case LengthModifier::AsInt64:
507         return ArgType(Ctx.LongLongTy, "__int64");
508       case LengthModifier::AsIntMax:
509         return ArgType(Ctx.getIntMaxType(), "intmax_t");
510       case LengthModifier::AsSizeT:
511         return ArgType::makeSizeT(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
512       case LengthModifier::AsInt3264:
513         return Ctx.getTargetInfo().getTriple().isArch64Bit()
514                    ? ArgType(Ctx.LongLongTy, "__int64")
515                    : ArgType(Ctx.IntTy, "__int32");
516       case LengthModifier::AsPtrDiff:
517         return ArgType::makePtrdiffT(
518             ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
519       case LengthModifier::AsAllocate:
520       case LengthModifier::AsMAllocate:
521       case LengthModifier::AsWide:
522         return ArgType::Invalid();
523     }
524 
525   if (CS.isUIntArg())
526     switch (LM.getKind()) {
527       case LengthModifier::AsLongDouble:
528         // GNU extension.
529         return Ctx.UnsignedLongLongTy;
530       case LengthModifier::None:
531         return Ctx.UnsignedIntTy;
532       case LengthModifier::AsInt32:
533         return ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
534       case LengthModifier::AsChar: return Ctx.UnsignedCharTy;
535       case LengthModifier::AsShort: return Ctx.UnsignedShortTy;
536       case LengthModifier::AsLong: return Ctx.UnsignedLongTy;
537       case LengthModifier::AsLongLong:
538       case LengthModifier::AsQuad:
539         return Ctx.UnsignedLongLongTy;
540       case LengthModifier::AsInt64:
541         return ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64");
542       case LengthModifier::AsIntMax:
543         return ArgType(Ctx.getUIntMaxType(), "uintmax_t");
544       case LengthModifier::AsSizeT:
545         return ArgType::makeSizeT(ArgType(Ctx.getSizeType(), "size_t"));
546       case LengthModifier::AsInt3264:
547         return Ctx.getTargetInfo().getTriple().isArch64Bit()
548                    ? ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64")
549                    : ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
550       case LengthModifier::AsPtrDiff:
551         return ArgType::makePtrdiffT(
552             ArgType(Ctx.getUnsignedPointerDiffType(), "unsigned ptrdiff_t"));
553       case LengthModifier::AsAllocate:
554       case LengthModifier::AsMAllocate:
555       case LengthModifier::AsWide:
556         return ArgType::Invalid();
557     }
558 
559   if (CS.isDoubleArg()) {
560     if (LM.getKind() == LengthModifier::AsLongDouble)
561       return Ctx.LongDoubleTy;
562     return Ctx.DoubleTy;
563   }
564 
565   if (CS.getKind() == ConversionSpecifier::nArg) {
566     switch (LM.getKind()) {
567       case LengthModifier::None:
568         return ArgType::PtrTo(Ctx.IntTy);
569       case LengthModifier::AsChar:
570         return ArgType::PtrTo(Ctx.SignedCharTy);
571       case LengthModifier::AsShort:
572         return ArgType::PtrTo(Ctx.ShortTy);
573       case LengthModifier::AsLong:
574         return ArgType::PtrTo(Ctx.LongTy);
575       case LengthModifier::AsLongLong:
576       case LengthModifier::AsQuad:
577         return ArgType::PtrTo(Ctx.LongLongTy);
578       case LengthModifier::AsIntMax:
579         return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
580       case LengthModifier::AsSizeT:
581         return ArgType::PtrTo(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
582       case LengthModifier::AsPtrDiff:
583         return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
584       case LengthModifier::AsLongDouble:
585         return ArgType(); // FIXME: Is this a known extension?
586       case LengthModifier::AsAllocate:
587       case LengthModifier::AsMAllocate:
588       case LengthModifier::AsInt32:
589       case LengthModifier::AsInt3264:
590       case LengthModifier::AsInt64:
591       case LengthModifier::AsWide:
592         return ArgType::Invalid();
593     }
594   }
595 
596   switch (CS.getKind()) {
597     case ConversionSpecifier::sArg:
598       if (LM.getKind() == LengthModifier::AsWideChar) {
599         if (IsObjCLiteral)
600           return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
601                          "const unichar *");
602         return ArgType(ArgType::WCStrTy, "wchar_t *");
603       }
604       if (LM.getKind() == LengthModifier::AsWide)
605         return ArgType(ArgType::WCStrTy, "wchar_t *");
606       return ArgType::CStrTy;
607     case ConversionSpecifier::SArg:
608       if (IsObjCLiteral)
609         return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()),
610                        "const unichar *");
611       if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
612           LM.getKind() == LengthModifier::AsShort)
613         return ArgType::CStrTy;
614       return ArgType(ArgType::WCStrTy, "wchar_t *");
615     case ConversionSpecifier::CArg:
616       if (IsObjCLiteral)
617         return ArgType(Ctx.UnsignedShortTy, "unichar");
618       if (Ctx.getTargetInfo().getTriple().isOSMSVCRT() &&
619           LM.getKind() == LengthModifier::AsShort)
620         return Ctx.IntTy;
621       return ArgType(Ctx.WideCharTy, "wchar_t");
622     case ConversionSpecifier::pArg:
623     case ConversionSpecifier::PArg:
624       return ArgType::CPointerTy;
625     case ConversionSpecifier::ObjCObjArg:
626       return ArgType::ObjCPointerTy;
627     default:
628       break;
629   }
630 
631   // FIXME: Handle other cases.
632   return ArgType();
633 }
634 
635 bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
636                               ASTContext &Ctx, bool IsObjCLiteral) {
637   // %n is different from other conversion specifiers; don't try to fix it.
638   if (CS.getKind() == ConversionSpecifier::nArg)
639     return false;
640 
641   // Handle Objective-C objects first. Note that while the '%@' specifier will
642   // not warn for structure pointer or void pointer arguments (because that's
643   // how CoreFoundation objects are implemented), we only show a fixit for '%@'
644   // if we know it's an object (block, id, class, or __attribute__((NSObject))).
645   if (QT->isObjCRetainableType()) {
646     if (!IsObjCLiteral)
647       return false;
648 
649     CS.setKind(ConversionSpecifier::ObjCObjArg);
650 
651     // Disable irrelevant flags
652     HasThousandsGrouping = false;
653     HasPlusPrefix = false;
654     HasSpacePrefix = false;
655     HasAlternativeForm = false;
656     HasLeadingZeroes = false;
657     Precision.setHowSpecified(OptionalAmount::NotSpecified);
658     LM.setKind(LengthModifier::None);
659 
660     return true;
661   }
662 
663   // Handle strings next (char *, wchar_t *)
664   if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
665     CS.setKind(ConversionSpecifier::sArg);
666 
667     // Disable irrelevant flags
668     HasAlternativeForm = 0;
669     HasLeadingZeroes = 0;
670 
671     // Set the long length modifier for wide characters
672     if (QT->getPointeeType()->isWideCharType())
673       LM.setKind(LengthModifier::AsWideChar);
674     else
675       LM.setKind(LengthModifier::None);
676 
677     return true;
678   }
679 
680   // If it's an enum, get its underlying type.
681   if (const EnumType *ETy = QT->getAs<EnumType>())
682     QT = ETy->getDecl()->getIntegerType();
683 
684   // We can only work with builtin types.
685   const BuiltinType *BT = QT->getAs<BuiltinType>();
686   if (!BT)
687     return false;
688 
689   // Set length modifier
690   switch (BT->getKind()) {
691   case BuiltinType::Bool:
692   case BuiltinType::WChar_U:
693   case BuiltinType::WChar_S:
694   case BuiltinType::Char8: // FIXME: Treat like 'char'?
695   case BuiltinType::Char16:
696   case BuiltinType::Char32:
697   case BuiltinType::UInt128:
698   case BuiltinType::Int128:
699   case BuiltinType::Half:
700   case BuiltinType::Float16:
701   case BuiltinType::Float128:
702   case BuiltinType::ShortAccum:
703   case BuiltinType::Accum:
704   case BuiltinType::LongAccum:
705   case BuiltinType::UShortAccum:
706   case BuiltinType::UAccum:
707   case BuiltinType::ULongAccum:
708   case BuiltinType::ShortFract:
709   case BuiltinType::Fract:
710   case BuiltinType::LongFract:
711   case BuiltinType::UShortFract:
712   case BuiltinType::UFract:
713   case BuiltinType::ULongFract:
714   case BuiltinType::SatShortAccum:
715   case BuiltinType::SatAccum:
716   case BuiltinType::SatLongAccum:
717   case BuiltinType::SatUShortAccum:
718   case BuiltinType::SatUAccum:
719   case BuiltinType::SatULongAccum:
720   case BuiltinType::SatShortFract:
721   case BuiltinType::SatFract:
722   case BuiltinType::SatLongFract:
723   case BuiltinType::SatUShortFract:
724   case BuiltinType::SatUFract:
725   case BuiltinType::SatULongFract:
726     // Various types which are non-trivial to correct.
727     return false;
728 
729 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
730   case BuiltinType::Id:
731 #include "clang/Basic/OpenCLImageTypes.def"
732 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
733   case BuiltinType::Id:
734 #include "clang/Basic/OpenCLExtensionTypes.def"
735 #define SIGNED_TYPE(Id, SingletonId)
736 #define UNSIGNED_TYPE(Id, SingletonId)
737 #define FLOATING_TYPE(Id, SingletonId)
738 #define BUILTIN_TYPE(Id, SingletonId) \
739   case BuiltinType::Id:
740 #include "clang/AST/BuiltinTypes.def"
741     // Misc other stuff which doesn't make sense here.
742     return false;
743 
744   case BuiltinType::UInt:
745   case BuiltinType::Int:
746   case BuiltinType::Float:
747   case BuiltinType::Double:
748     LM.setKind(LengthModifier::None);
749     break;
750 
751   case BuiltinType::Char_U:
752   case BuiltinType::UChar:
753   case BuiltinType::Char_S:
754   case BuiltinType::SChar:
755     LM.setKind(LengthModifier::AsChar);
756     break;
757 
758   case BuiltinType::Short:
759   case BuiltinType::UShort:
760     LM.setKind(LengthModifier::AsShort);
761     break;
762 
763   case BuiltinType::Long:
764   case BuiltinType::ULong:
765     LM.setKind(LengthModifier::AsLong);
766     break;
767 
768   case BuiltinType::LongLong:
769   case BuiltinType::ULongLong:
770     LM.setKind(LengthModifier::AsLongLong);
771     break;
772 
773   case BuiltinType::LongDouble:
774     LM.setKind(LengthModifier::AsLongDouble);
775     break;
776   }
777 
778   // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99.
779   if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus11))
780     namedTypeToLengthModifier(QT, LM);
781 
782   // If fixing the length modifier was enough, we might be done.
783   if (hasValidLengthModifier(Ctx.getTargetInfo())) {
784     // If we're going to offer a fix anyway, make sure the sign matches.
785     switch (CS.getKind()) {
786     case ConversionSpecifier::uArg:
787     case ConversionSpecifier::UArg:
788       if (QT->isSignedIntegerType())
789         CS.setKind(clang::analyze_format_string::ConversionSpecifier::dArg);
790       break;
791     case ConversionSpecifier::dArg:
792     case ConversionSpecifier::DArg:
793     case ConversionSpecifier::iArg:
794       if (QT->isUnsignedIntegerType() && !HasPlusPrefix)
795         CS.setKind(clang::analyze_format_string::ConversionSpecifier::uArg);
796       break;
797     default:
798       // Other specifiers do not have signed/unsigned variants.
799       break;
800     }
801 
802     const analyze_printf::ArgType &ATR = getArgType(Ctx, IsObjCLiteral);
803     if (ATR.isValid() && ATR.matchesType(Ctx, QT))
804       return true;
805   }
806 
807   // Set conversion specifier and disable any flags which do not apply to it.
808   // Let typedefs to char fall through to int, as %c is silly for uint8_t.
809   if (!isa<TypedefType>(QT) && QT->isCharType()) {
810     CS.setKind(ConversionSpecifier::cArg);
811     LM.setKind(LengthModifier::None);
812     Precision.setHowSpecified(OptionalAmount::NotSpecified);
813     HasAlternativeForm = 0;
814     HasLeadingZeroes = 0;
815     HasPlusPrefix = 0;
816   }
817   // Test for Floating type first as LongDouble can pass isUnsignedIntegerType
818   else if (QT->isRealFloatingType()) {
819     CS.setKind(ConversionSpecifier::fArg);
820   }
821   else if (QT->isSignedIntegerType()) {
822     CS.setKind(ConversionSpecifier::dArg);
823     HasAlternativeForm = 0;
824   }
825   else if (QT->isUnsignedIntegerType()) {
826     CS.setKind(ConversionSpecifier::uArg);
827     HasAlternativeForm = 0;
828     HasPlusPrefix = 0;
829   } else {
830     llvm_unreachable("Unexpected type");
831   }
832 
833   return true;
834 }
835 
836 void PrintfSpecifier::toString(raw_ostream &os) const {
837   // Whilst some features have no defined order, we are using the order
838   // appearing in the C99 standard (ISO/IEC 9899:1999 (E) 7.19.6.1)
839   os << "%";
840 
841   // Positional args
842   if (usesPositionalArg()) {
843     os << getPositionalArgIndex() << "$";
844   }
845 
846   // Conversion flags
847   if (IsLeftJustified)    os << "-";
848   if (HasPlusPrefix)      os << "+";
849   if (HasSpacePrefix)     os << " ";
850   if (HasAlternativeForm) os << "#";
851   if (HasLeadingZeroes)   os << "0";
852 
853   // Minimum field width
854   FieldWidth.toString(os);
855   // Precision
856   Precision.toString(os);
857   // Length modifier
858   os << LM.toString();
859   // Conversion specifier
860   os << CS.toString();
861 }
862 
863 bool PrintfSpecifier::hasValidPlusPrefix() const {
864   if (!HasPlusPrefix)
865     return true;
866 
867   // The plus prefix only makes sense for signed conversions
868   switch (CS.getKind()) {
869   case ConversionSpecifier::dArg:
870   case ConversionSpecifier::DArg:
871   case ConversionSpecifier::iArg:
872   case ConversionSpecifier::fArg:
873   case ConversionSpecifier::FArg:
874   case ConversionSpecifier::eArg:
875   case ConversionSpecifier::EArg:
876   case ConversionSpecifier::gArg:
877   case ConversionSpecifier::GArg:
878   case ConversionSpecifier::aArg:
879   case ConversionSpecifier::AArg:
880   case ConversionSpecifier::FreeBSDrArg:
881   case ConversionSpecifier::FreeBSDyArg:
882     return true;
883 
884   default:
885     return false;
886   }
887 }
888 
889 bool PrintfSpecifier::hasValidAlternativeForm() const {
890   if (!HasAlternativeForm)
891     return true;
892 
893   // Alternate form flag only valid with the oxXaAeEfFgG conversions
894   switch (CS.getKind()) {
895   case ConversionSpecifier::oArg:
896   case ConversionSpecifier::OArg:
897   case ConversionSpecifier::xArg:
898   case ConversionSpecifier::XArg:
899   case ConversionSpecifier::aArg:
900   case ConversionSpecifier::AArg:
901   case ConversionSpecifier::eArg:
902   case ConversionSpecifier::EArg:
903   case ConversionSpecifier::fArg:
904   case ConversionSpecifier::FArg:
905   case ConversionSpecifier::gArg:
906   case ConversionSpecifier::GArg:
907   case ConversionSpecifier::FreeBSDrArg:
908   case ConversionSpecifier::FreeBSDyArg:
909     return true;
910 
911   default:
912     return false;
913   }
914 }
915 
916 bool PrintfSpecifier::hasValidLeadingZeros() const {
917   if (!HasLeadingZeroes)
918     return true;
919 
920   // Leading zeroes flag only valid with the diouxXaAeEfFgG conversions
921   switch (CS.getKind()) {
922   case ConversionSpecifier::dArg:
923   case ConversionSpecifier::DArg:
924   case ConversionSpecifier::iArg:
925   case ConversionSpecifier::oArg:
926   case ConversionSpecifier::OArg:
927   case ConversionSpecifier::uArg:
928   case ConversionSpecifier::UArg:
929   case ConversionSpecifier::xArg:
930   case ConversionSpecifier::XArg:
931   case ConversionSpecifier::aArg:
932   case ConversionSpecifier::AArg:
933   case ConversionSpecifier::eArg:
934   case ConversionSpecifier::EArg:
935   case ConversionSpecifier::fArg:
936   case ConversionSpecifier::FArg:
937   case ConversionSpecifier::gArg:
938   case ConversionSpecifier::GArg:
939   case ConversionSpecifier::FreeBSDrArg:
940   case ConversionSpecifier::FreeBSDyArg:
941     return true;
942 
943   default:
944     return false;
945   }
946 }
947 
948 bool PrintfSpecifier::hasValidSpacePrefix() const {
949   if (!HasSpacePrefix)
950     return true;
951 
952   // The space prefix only makes sense for signed conversions
953   switch (CS.getKind()) {
954   case ConversionSpecifier::dArg:
955   case ConversionSpecifier::DArg:
956   case ConversionSpecifier::iArg:
957   case ConversionSpecifier::fArg:
958   case ConversionSpecifier::FArg:
959   case ConversionSpecifier::eArg:
960   case ConversionSpecifier::EArg:
961   case ConversionSpecifier::gArg:
962   case ConversionSpecifier::GArg:
963   case ConversionSpecifier::aArg:
964   case ConversionSpecifier::AArg:
965   case ConversionSpecifier::FreeBSDrArg:
966   case ConversionSpecifier::FreeBSDyArg:
967     return true;
968 
969   default:
970     return false;
971   }
972 }
973 
974 bool PrintfSpecifier::hasValidLeftJustified() const {
975   if (!IsLeftJustified)
976     return true;
977 
978   // The left justified flag is valid for all conversions except n
979   switch (CS.getKind()) {
980   case ConversionSpecifier::nArg:
981     return false;
982 
983   default:
984     return true;
985   }
986 }
987 
988 bool PrintfSpecifier::hasValidThousandsGroupingPrefix() const {
989   if (!HasThousandsGrouping)
990     return true;
991 
992   switch (CS.getKind()) {
993     case ConversionSpecifier::dArg:
994     case ConversionSpecifier::DArg:
995     case ConversionSpecifier::iArg:
996     case ConversionSpecifier::uArg:
997     case ConversionSpecifier::UArg:
998     case ConversionSpecifier::fArg:
999     case ConversionSpecifier::FArg:
1000     case ConversionSpecifier::gArg:
1001     case ConversionSpecifier::GArg:
1002       return true;
1003     default:
1004       return false;
1005   }
1006 }
1007 
1008 bool PrintfSpecifier::hasValidPrecision() const {
1009   if (Precision.getHowSpecified() == OptionalAmount::NotSpecified)
1010     return true;
1011 
1012   // Precision is only valid with the diouxXaAeEfFgGsP conversions
1013   switch (CS.getKind()) {
1014   case ConversionSpecifier::dArg:
1015   case ConversionSpecifier::DArg:
1016   case ConversionSpecifier::iArg:
1017   case ConversionSpecifier::oArg:
1018   case ConversionSpecifier::OArg:
1019   case ConversionSpecifier::uArg:
1020   case ConversionSpecifier::UArg:
1021   case ConversionSpecifier::xArg:
1022   case ConversionSpecifier::XArg:
1023   case ConversionSpecifier::aArg:
1024   case ConversionSpecifier::AArg:
1025   case ConversionSpecifier::eArg:
1026   case ConversionSpecifier::EArg:
1027   case ConversionSpecifier::fArg:
1028   case ConversionSpecifier::FArg:
1029   case ConversionSpecifier::gArg:
1030   case ConversionSpecifier::GArg:
1031   case ConversionSpecifier::sArg:
1032   case ConversionSpecifier::FreeBSDrArg:
1033   case ConversionSpecifier::FreeBSDyArg:
1034   case ConversionSpecifier::PArg:
1035   case ConversionSpecifier::VArg:
1036     return true;
1037 
1038   default:
1039     return false;
1040   }
1041 }
1042 bool PrintfSpecifier::hasValidFieldWidth() const {
1043   if (FieldWidth.getHowSpecified() == OptionalAmount::NotSpecified)
1044       return true;
1045 
1046   // The field width is valid for all conversions except n
1047   switch (CS.getKind()) {
1048   case ConversionSpecifier::nArg:
1049     return false;
1050 
1051   default:
1052     return true;
1053   }
1054 }
1055