Coverage Report

Created: 2017-10-03 07:32

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