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