Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/AST/FormatString.cpp
Line
Count
Source (jump to first uncovered line)
1
// FormatString.cpp - Common stuff for handling printf/scanf formats -*- C++ -*-
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// Shared details for processing format strings of printf and scanf
10
// (and friends).
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "FormatStringParsing.h"
15
#include "clang/Basic/LangOptions.h"
16
#include "clang/Basic/TargetInfo.h"
17
#include "llvm/Support/ConvertUTF.h"
18
19
using clang::analyze_format_string::ArgType;
20
using clang::analyze_format_string::FormatStringHandler;
21
using clang::analyze_format_string::FormatSpecifier;
22
using clang::analyze_format_string::LengthModifier;
23
using clang::analyze_format_string::OptionalAmount;
24
using clang::analyze_format_string::PositionContext;
25
using clang::analyze_format_string::ConversionSpecifier;
26
using namespace clang;
27
28
// Key function to FormatStringHandler.
29
43.0k
FormatStringHandler::~FormatStringHandler() {}
30
31
//===----------------------------------------------------------------------===//
32
// Functions for parsing format strings components in both printf and
33
// scanf format strings.
34
//===----------------------------------------------------------------------===//
35
36
OptionalAmount
37
117k
clang::analyze_format_string::ParseAmount(const char *&Beg, const char *E) {
38
117k
  const char *I = Beg;
39
117k
  UpdateOnReturn <const char*> UpdateBeg(Beg, I);
40
117k
41
117k
  unsigned accumulator = 0;
42
117k
  bool hasDigits = false;
43
117k
44
168k
  for ( ; I != E; 
++I51.8k
) {
45
168k
    char c = *I;
46
168k
    if (c >= '0' && 
c <= '9'163k
) {
47
51.8k
      hasDigits = true;
48
51.8k
      accumulator = (accumulator * 10) + (c - '0');
49
51.8k
      continue;
50
51.8k
    }
51
117k
52
117k
    if (hasDigits)
53
23.8k
      return OptionalAmount(OptionalAmount::Constant, accumulator, Beg, I - Beg,
54
23.8k
          false);
55
93.3k
56
93.3k
    break;
57
93.3k
  }
58
117k
59
117k
  
return OptionalAmount()93.3k
;
60
117k
}
61
62
OptionalAmount
63
clang::analyze_format_string::ParseNonPositionAmount(const char *&Beg,
64
                                                     const char *E,
65
58.3k
                                                     unsigned &argIndex) {
66
58.3k
  if (*Beg == '*') {
67
852
    ++Beg;
68
852
    return OptionalAmount(OptionalAmount::Arg, argIndex++, Beg, 0, false);
69
852
  }
70
57.4k
71
57.4k
  return ParseAmount(Beg, E);
72
57.4k
}
73
74
OptionalAmount
75
clang::analyze_format_string::ParsePositionAmount(FormatStringHandler &H,
76
                                                  const char *Start,
77
                                                  const char *&Beg,
78
                                                  const char *E,
79
63
                                                  PositionContext p) {
80
63
  if (*Beg == '*') {
81
10
    const char *I = Beg + 1;
82
10
    const OptionalAmount &Amt = ParseAmount(I, E);
83
10
84
10
    if (Amt.getHowSpecified() == OptionalAmount::NotSpecified) {
85
0
      H.HandleInvalidPosition(Beg, I - Beg, p);
86
0
      return OptionalAmount(false);
87
0
    }
88
10
89
10
    if (I == E) {
90
0
      // No more characters left?
91
0
      H.HandleIncompleteSpecifier(Start, E - Start);
92
0
      return OptionalAmount(false);
93
0
    }
94
10
95
10
    assert(Amt.getHowSpecified() == OptionalAmount::Constant);
96
10
97
10
    if (*I == '$') {
98
10
      // Handle positional arguments
99
10
100
10
      // Special case: '*0$', since this is an easy mistake.
101
10
      if (Amt.getConstantAmount() == 0) {
102
2
        H.HandleZeroPosition(Beg, I - Beg + 1);
103
2
        return OptionalAmount(false);
104
2
      }
105
8
106
8
      const char *Tmp = Beg;
107
8
      Beg = ++I;
108
8
109
8
      return OptionalAmount(OptionalAmount::Arg, Amt.getConstantAmount() - 1,
110
8
                            Tmp, 0, true);
111
8
    }
112
0
113
0
    H.HandleInvalidPosition(Beg, I - Beg, p);
114
0
    return OptionalAmount(false);
115
0
  }
116
53
117
53
  return ParseAmount(Beg, E);
118
53
}
119
120
121
bool
122
clang::analyze_format_string::ParseFieldWidth(FormatStringHandler &H,
123
                                              FormatSpecifier &CS,
124
                                              const char *Start,
125
                                              const char *&Beg, const char *E,
126
56.2k
                                              unsigned *argIndex) {
127
56.2k
  // FIXME: Support negative field widths.
128
56.2k
  if (argIndex) {
129
56.1k
    CS.setFieldWidth(ParseNonPositionAmount(Beg, E, *argIndex));
130
56.1k
  }
131
55
  else {
132
55
    const OptionalAmount Amt =
133
55
      ParsePositionAmount(H, Start, Beg, E,
134
55
                          analyze_format_string::FieldWidthPos);
135
55
136
55
    if (Amt.isInvalid())
137
2
      return true;
138
53
    CS.setFieldWidth(Amt);
139
53
  }
140
56.2k
  
return false56.2k
;
141
56.2k
}
142
143
bool
144
clang::analyze_format_string::ParseArgPosition(FormatStringHandler &H,
145
                                               FormatSpecifier &FS,
146
                                               const char *Start,
147
                                               const char *&Beg,
148
57.8k
                                               const char *E) {
149
57.8k
  const char *I = Beg;
150
57.8k
151
57.8k
  const OptionalAmount &Amt = ParseAmount(I, E);
152
57.8k
153
57.8k
  if (I == E) {
154
0
    // No more characters left?
155
0
    H.HandleIncompleteSpecifier(Start, E - Start);
156
0
    return true;
157
0
  }
158
57.8k
159
57.8k
  if (Amt.getHowSpecified() == OptionalAmount::Constant && 
*(I++) == '$'11.0k
) {
160
69
    // Warn that positional arguments are non-standard.
161
69
    H.HandlePosition(Start, I - Start);
162
69
163
69
    // Special case: '%0$', since this is an easy mistake.
164
69
    if (Amt.getConstantAmount() == 0) {
165
6
      H.HandleZeroPosition(Start, I - Start);
166
6
      return true;
167
6
    }
168
63
169
63
    FS.setArgIndex(Amt.getConstantAmount() - 1);
170
63
    FS.setUsesPositionalArg();
171
63
    // Update the caller's pointer if we decided to consume
172
63
    // these characters.
173
63
    Beg = I;
174
63
    return false;
175
63
  }
176
57.7k
177
57.7k
  return false;
178
57.7k
}
179
180
bool
181
clang::analyze_format_string::ParseVectorModifier(FormatStringHandler &H,
182
                                                  FormatSpecifier &FS,
183
                                                  const char *&I,
184
                                                  const char *E,
185
56.2k
                                                  const LangOptions &LO) {
186
56.2k
  if (!LO.OpenCL)
187
56.0k
    return false;
188
174
189
174
  const char *Start = I;
190
174
  if (*I == 'v') {
191
168
    ++I;
192
168
193
168
    if (I == E) {
194
2
      H.HandleIncompleteSpecifier(Start, E - Start);
195
2
      return true;
196
2
    }
197
166
198
166
    OptionalAmount NumElts = ParseAmount(I, E);
199
166
    if (NumElts.getHowSpecified() != OptionalAmount::Constant) {
200
10
      H.HandleIncompleteSpecifier(Start, E - Start);
201
10
      return true;
202
10
    }
203
156
204
156
    FS.setVectorNumElts(NumElts);
205
156
  }
206
174
207
174
  
return false162
;
208
174
}
209
210
bool
211
clang::analyze_format_string::ParseLengthModifier(FormatSpecifier &FS,
212
                                                  const char *&I,
213
                                                  const char *E,
214
                                                  const LangOptions &LO,
215
57.8k
                                                  bool IsScanf) {
216
57.8k
  LengthModifier::Kind lmKind = LengthModifier::None;
217
57.8k
  const char *lmPosition = I;
218
57.8k
  switch (*I) {
219
57.8k
    default:
220
43.6k
      return false;
221
57.8k
    case 'h':
222
2.85k
      ++I;
223
2.85k
      if (I != E && *I == 'h') {
224
1.74k
        ++I;
225
1.74k
        lmKind = LengthModifier::AsChar;
226
1.74k
      } else 
if (1.11k
I != E1.11k
&&
*I == 'l'1.11k
&&
LO.OpenCL43
) {
227
39
        ++I;
228
39
        lmKind = LengthModifier::AsShortLong;
229
1.07k
      } else {
230
1.07k
        lmKind = LengthModifier::AsShort;
231
1.07k
      }
232
2.85k
      break;
233
57.8k
    case 'l':
234
10.9k
      ++I;
235
10.9k
      if (I != E && 
*I == 'l'10.9k
) {
236
9.51k
        ++I;
237
9.51k
        lmKind = LengthModifier::AsLongLong;
238
9.51k
      } else {
239
1.43k
        lmKind = LengthModifier::AsLong;
240
1.43k
      }
241
10.9k
      break;
242
57.8k
    
case 'j': lmKind = LengthModifier::AsIntMax; ++I; break19
;
243
57.8k
    
case 'z': lmKind = LengthModifier::AsSizeT; ++I; break73
;
244
57.8k
    
case 't': lmKind = LengthModifier::AsPtrDiff; ++I; break67
;
245
57.8k
    
case 'L': lmKind = LengthModifier::AsLongDouble; ++I; break97
;
246
57.8k
    
case 'q': lmKind = LengthModifier::AsQuad; ++I; break24
;
247
57.8k
    case 'a':
248
38
      if (IsScanf && 
!LO.C9924
&&
!LO.CPlusPlus1115
) {
249
9
        // For scanf in C90, look at the next character to see if this should
250
9
        // be parsed as the GNU extension 'a' length modifier. If not, this
251
9
        // will be parsed as a conversion specifier.
252
9
        ++I;
253
9
        if (I != E && 
(8
*I == 's'8
||
*I == 'S'5
||
*I == '['4
)) {
254
6
          lmKind = LengthModifier::AsAllocate;
255
6
          break;
256
6
        }
257
3
        --I;
258
3
      }
259
38
      
return false32
;
260
38
    case 'm':
261
36
      if (IsScanf) {
262
23
        lmKind = LengthModifier::AsMAllocate;
263
23
        ++I;
264
23
        break;
265
23
      }
266
13
      return false;
267
13
    // printf: AsInt64, AsInt32, AsInt3264
268
13
    // scanf:  AsInt64
269
13
    case 'I':
270
11
      if (I + 1 != E && I + 2 != E) {
271
10
        if (I[1] == '6' && 
I[2] == '4'3
) {
272
3
          I += 3;
273
3
          lmKind = LengthModifier::AsInt64;
274
3
          break;
275
3
        }
276
7
        if (IsScanf)
277
0
          return false;
278
7
279
7
        if (I[1] == '3' && 
I[2] == '2'3
) {
280
3
          I += 3;
281
3
          lmKind = LengthModifier::AsInt32;
282
3
          break;
283
3
        }
284
5
      }
285
5
      ++I;
286
5
      lmKind = LengthModifier::AsInt3264;
287
5
      break;
288
18
    case 'w':
289
18
      lmKind = LengthModifier::AsWide; ++I; break;
290
14.1k
  }
291
14.1k
  LengthModifier lm(lmPosition, lmKind);
292
14.1k
  FS.setLengthModifier(lm);
293
14.1k
  return true;
294
14.1k
}
295
296
bool clang::analyze_format_string::ParseUTF8InvalidSpecifier(
297
99
    const char *SpecifierBegin, const char *FmtStrEnd, unsigned &Len) {
298
99
  if (SpecifierBegin + 1 >= FmtStrEnd)
299
0
    return false;
300
99
301
99
  const llvm::UTF8 *SB =
302
99
      reinterpret_cast<const llvm::UTF8 *>(SpecifierBegin + 1);
303
99
  const llvm::UTF8 *SE = reinterpret_cast<const llvm::UTF8 *>(FmtStrEnd);
304
99
  const char FirstByte = *SB;
305
99
306
99
  // If the invalid specifier is a multibyte UTF-8 string, return the
307
99
  // total length accordingly so that the conversion specifier can be
308
99
  // properly updated to reflect a complete UTF-8 specifier.
309
99
  unsigned NumBytes = llvm::getNumBytesForUTF8(FirstByte);
310
99
  if (NumBytes == 1)
311
79
    return false;
312
20
  if (SB + NumBytes > SE)
313
4
    return false;
314
16
315
16
  Len = NumBytes + 1;
316
16
  return true;
317
16
}
318
319
//===----------------------------------------------------------------------===//
320
// Methods on ArgType.
321
//===----------------------------------------------------------------------===//
322
323
clang::analyze_format_string::ArgType::MatchKind
324
61.3k
ArgType::matchesType(ASTContext &C, QualType argTy) const {
325
61.3k
  if (Ptr) {
326
1.67k
    // It has to be a pointer.
327
1.67k
    const PointerType *PT = argTy->getAs<PointerType>();
328
1.67k
    if (!PT)
329
10
      return NoMatch;
330
1.66k
331
1.66k
    // We cannot write through a const qualified pointer.
332
1.66k
    if (PT->getPointeeType().isConstQualified())
333
22
      return NoMatch;
334
1.63k
335
1.63k
    argTy = PT->getPointeeType();
336
1.63k
  }
337
61.3k
338
61.3k
  switch (K) {
339
61.3k
    case InvalidTy:
340
0
      llvm_unreachable("ArgType must be valid");
341
61.3k
342
61.3k
    case UnknownTy:
343
8
      return Match;
344
61.3k
345
61.3k
    case AnyCharTy: {
346
1.60k
      if (const EnumType *ETy = argTy->getAs<EnumType>()) {
347
20
        // If the enum is incomplete we know nothing about the underlying type.
348
20
        // Assume that it's 'int'.
349
20
        if (!ETy->getDecl()->isComplete())
350
2
          return NoMatch;
351
18
        argTy = ETy->getDecl()->getIntegerType();
352
18
      }
353
1.60k
354
1.60k
      
if (const BuiltinType *1.59k
BT1.59k
= argTy->getAs<BuiltinType>())
355
1.59k
        switch (BT->getKind()) {
356
1.59k
          default:
357
632
            break;
358
1.59k
          case BuiltinType::Char_S:
359
967
          case BuiltinType::SChar:
360
967
          case BuiltinType::UChar:
361
967
          case BuiltinType::Char_U:
362
967
            return Match;
363
632
        }
364
632
      return NoMatch;
365
632
    }
366
632
367
31.9k
    case SpecificTy: {
368
31.9k
      if (const EnumType *ETy = argTy->getAs<EnumType>()) {
369
54
        // If the enum is incomplete we know nothing about the underlying type.
370
54
        // Assume that it's 'int'.
371
54
        if (!ETy->getDecl()->isComplete())
372
4
          argTy = C.IntTy;
373
50
        else
374
50
          argTy = ETy->getDecl()->getIntegerType();
375
54
      }
376
31.9k
      argTy = C.getCanonicalType(argTy).getUnqualifiedType();
377
31.9k
378
31.9k
      if (T == argTy)
379
27.5k
        return Match;
380
4.35k
      // Check for "compatible types".
381
4.35k
      if (const BuiltinType *BT = argTy->getAs<BuiltinType>())
382
4.13k
        switch (BT->getKind()) {
383
4.13k
          default:
384
162
            break;
385
4.13k
          case BuiltinType::Char_S:
386
58
          case BuiltinType::SChar:
387
58
          case BuiltinType::Char_U:
388
58
          case BuiltinType::UChar:
389
58
            return T == C.UnsignedCharTy || 
T == C.SignedCharTy52
?
Match14
390
58
                                                                : 
NoMatch44
;
391
58
          case BuiltinType::Short:
392
39
            return T == C.UnsignedShortTy ? 
Match8
:
NoMatch31
;
393
58
          case BuiltinType::UShort:
394
12
            return T == C.ShortTy ? 
Match4
:
NoMatch8
;
395
2.68k
          case BuiltinType::Int:
396
2.68k
            return T == C.UnsignedIntTy ? 
Match363
:
NoMatch2.32k
;
397
529
          case BuiltinType::UInt:
398
529
            return T == C.IntTy ? 
Match459
:
NoMatch70
;
399
183
          case BuiltinType::Long:
400
183
            return T == C.UnsignedLongTy ? 
Match66
:
NoMatch117
;
401
236
          case BuiltinType::ULong:
402
236
            return T == C.LongTy ? 
Match118
:
NoMatch118
;
403
194
          case BuiltinType::LongLong:
404
194
            return T == C.UnsignedLongLongTy ? 
Match178
:
NoMatch16
;
405
58
          case BuiltinType::ULongLong:
406
39
            return T == C.LongLongTy ? 
Match32
:
NoMatch7
;
407
379
        }
408
379
      return NoMatch;
409
379
    }
410
379
411
27.1k
    case CStrTy: {
412
27.1k
      const PointerType *PT = argTy->getAs<PointerType>();
413
27.1k
      if (!PT)
414
402
        return NoMatch;
415
26.7k
      QualType pointeeTy = PT->getPointeeType();
416
26.7k
      if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>())
417
26.7k
        switch (BT->getKind()) {
418
26.7k
          case BuiltinType::Void:
419
26.7k
          case BuiltinType::Char_U:
420
26.7k
          case BuiltinType::UChar:
421
26.7k
          case BuiltinType::Char_S:
422
26.7k
          case BuiltinType::SChar:
423
26.7k
            return Match;
424
26.7k
          default:
425
2
            break;
426
10
        }
427
10
428
10
      return NoMatch;
429
10
    }
430
10
431
133
    case WCStrTy: {
432
133
      const PointerType *PT = argTy->getAs<PointerType>();
433
133
      if (!PT)
434
109
        return NoMatch;
435
24
      QualType pointeeTy =
436
24
        C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType();
437
24
      return pointeeTy == C.getWideCharType() ? 
Match16
:
NoMatch8
;
438
24
    }
439
24
440
24
    case WIntTy: {
441
16
      QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType();
442
16
443
16
      if (C.getCanonicalType(argTy).getUnqualifiedType() == WInt)
444
8
        return Match;
445
8
446
8
      QualType PromoArg = argTy->isPromotableIntegerType()
447
8
                              ? 
C.getPromotedIntegerType(argTy)0
448
8
                              : argTy;
449
8
      PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType();
450
8
451
8
      // If the promoted argument is the corresponding signed type of the
452
8
      // wint_t type, then it should match.
453
8
      if (PromoArg->hasSignedIntegerRepresentation() &&
454
8
          
C.getCorrespondingUnsignedType(PromoArg) == WInt2
)
455
0
        return Match;
456
8
457
8
      return WInt == PromoArg ? 
Match0
: NoMatch;
458
8
    }
459
8
460
394
    case CPointerTy:
461
394
      if (argTy->isVoidPointerType()) {
462
120
        return Match;
463
274
      } if (argTy->isPointerType() || 
argTy->isObjCObjectPointerType()30
||
464
274
            
argTy->isBlockPointerType()22
||
argTy->isNullPtrType()21
) {
465
254
        return NoMatchPedantic;
466
254
      } else {
467
20
        return NoMatch;
468
20
      }
469
0
470
128
    case ObjCPointerTy: {
471
128
      if (argTy->getAs<ObjCObjectPointerType>() ||
472
128
          
argTy->getAs<BlockPointerType>()53
)
473
78
        return Match;
474
50
475
50
      // Handle implicit toll-free bridging.
476
50
      if (const PointerType *PT = argTy->getAs<PointerType>()) {
477
12
        // Things such as CFTypeRef are really just opaque pointers
478
12
        // to C structs representing CF types that can often be bridged
479
12
        // to Objective-C objects.  Since the compiler doesn't know which
480
12
        // structs can be toll-free bridged, we just accept them all.
481
12
        QualType pointee = PT->getPointeeType();
482
12
        if (pointee->getAsStructureType() || 
pointee->isVoidType()3
)
483
9
          return Match;
484
41
      }
485
41
      return NoMatch;
486
41
    }
487
0
  }
488
0
489
0
  llvm_unreachable("Invalid ArgType Kind!");
490
0
}
491
492
231
ArgType ArgType::makeVectorType(ASTContext &C, unsigned NumElts) const {
493
231
  // Check for valid vector element types.
494
231
  if (T.isNull())
495
20
    return ArgType::Invalid();
496
211
497
211
  QualType Vec = C.getExtVectorType(T, NumElts);
498
211
  return ArgType(Vec, Name);
499
211
}
500
501
1.18k
QualType ArgType::getRepresentativeType(ASTContext &C) const {
502
1.18k
  QualType Res;
503
1.18k
  switch (K) {
504
1.18k
    case InvalidTy:
505
0
      llvm_unreachable("No representative type for Invalid ArgType");
506
1.18k
    case UnknownTy:
507
0
      llvm_unreachable("No representative type for Unknown ArgType");
508
1.18k
    case AnyCharTy:
509
31
      Res = C.CharTy;
510
31
      break;
511
1.18k
    case SpecificTy:
512
742
      Res = T;
513
742
      break;
514
1.18k
    case CStrTy:
515
113
      Res = C.getPointerType(C.CharTy);
516
113
      break;
517
1.18k
    case WCStrTy:
518
18
      Res = C.getPointerType(C.getWideCharType());
519
18
      break;
520
1.18k
    case ObjCPointerTy:
521
23
      Res = C.ObjCBuiltinIdTy;
522
23
      break;
523
1.18k
    case CPointerTy:
524
250
      Res = C.VoidPtrTy;
525
250
      break;
526
1.18k
    case WIntTy: {
527
6
      Res = C.getWIntType();
528
6
      break;
529
1.18k
    }
530
1.18k
  }
531
1.18k
532
1.18k
  if (Ptr)
533
175
    Res = C.getPointerType(Res);
534
1.18k
  return Res;
535
1.18k
}
536
537
1.18k
std::string ArgType::getRepresentativeTypeName(ASTContext &C) const {
538
1.18k
  std::string S = getRepresentativeType(C).getAsString();
539
1.18k
540
1.18k
  std::string Alias;
541
1.18k
  if (Name) {
542
113
    // Use a specific name for this type, e.g. "size_t".
543
113
    Alias = Name;
544
113
    if (Ptr) {
545
39
      // If ArgType is actually a pointer to T, append an asterisk.
546
39
      Alias += (Alias[Alias.size()-1] == '*') ? 
"*"5
:
" *"34
;
547
39
    }
548
113
    // If Alias is the same as the underlying type, e.g. wchar_t, then drop it.
549
113
    if (S == Alias)
550
3
      Alias.clear();
551
113
  }
552
1.18k
553
1.18k
  if (!Alias.empty())
554
110
    return std::string("'") + Alias + "' (aka '" + S + "')";
555
1.07k
  return std::string("'") + S + "'";
556
1.07k
}
557
558
559
//===----------------------------------------------------------------------===//
560
// Methods on OptionalAmount.
561
//===----------------------------------------------------------------------===//
562
563
ArgType
564
820
analyze_format_string::OptionalAmount::getArgType(ASTContext &Ctx) const {
565
820
  return Ctx.IntTy;
566
820
}
567
568
//===----------------------------------------------------------------------===//
569
// Methods on LengthModifier.
570
//===----------------------------------------------------------------------===//
571
572
const char *
573
1.26k
analyze_format_string::LengthModifier::toString() const {
574
1.26k
  switch (kind) {
575
1.26k
  case AsChar:
576
35
    return "hh";
577
1.26k
  case AsShort:
578
71
    return "h";
579
1.26k
  case AsShortLong:
580
82
    return "hl";
581
1.26k
  case AsLong: // or AsWideChar
582
307
    return "l";
583
1.26k
  case AsLongLong:
584
155
    return "ll";
585
1.26k
  case AsQuad:
586
24
    return "q";
587
1.26k
  case AsIntMax:
588
8
    return "j";
589
1.26k
  case AsSizeT:
590
36
    return "z";
591
1.26k
  case AsPtrDiff:
592
4
    return "t";
593
1.26k
  case AsInt32:
594
3
    return "I32";
595
1.26k
  case AsInt3264:
596
5
    return "I";
597
1.26k
  case AsInt64:
598
3
    return "I64";
599
1.26k
  case AsLongDouble:
600
79
    return "L";
601
1.26k
  case AsAllocate:
602
6
    return "a";
603
1.26k
  case AsMAllocate:
604
23
    return "m";
605
1.26k
  case AsWide:
606
18
    return "w";
607
1.26k
  case None:
608
403
    return "";
609
0
  }
610
0
  return nullptr;
611
0
}
612
613
//===----------------------------------------------------------------------===//
614
// Methods on ConversionSpecifier.
615
//===----------------------------------------------------------------------===//
616
617
1.34k
const char *ConversionSpecifier::toString() const {
618
1.34k
  switch (kind) {
619
1.34k
  
case dArg: return "d"450
;
620
1.34k
  
case DArg: return "D"31
;
621
1.34k
  
case iArg: return "i"9
;
622
1.34k
  
case oArg: return "o"39
;
623
1.34k
  
case OArg: return "O"20
;
624
1.34k
  
case uArg: return "u"264
;
625
1.34k
  
case UArg: return "U"18
;
626
1.34k
  
case xArg: return "x"31
;
627
1.34k
  
case XArg: return "X"5
;
628
1.34k
  
case fArg: return "f"101
;
629
1.34k
  
case FArg: return "F"2
;
630
1.34k
  
case eArg: return "e"2
;
631
1.34k
  
case EArg: return "E"2
;
632
1.34k
  
case gArg: return "g"2
;
633
1.34k
  
case GArg: return "G"2
;
634
1.34k
  
case aArg: return "a"4
;
635
1.34k
  
case AArg: return "A"2
;
636
1.34k
  
case cArg: return "c"49
;
637
1.34k
  
case sArg: return "s"134
;
638
1.34k
  
case pArg: return "p"28
;
639
1.34k
  case PArg:
640
0
    return "P";
641
1.34k
  
case nArg: return "n"10
;
642
1.34k
  
case PercentArg: return "%"0
;
643
1.34k
  
case ScanListArg: return "["4
;
644
1.34k
  
case InvalidSpecifier: return nullptr0
;
645
1.34k
646
1.34k
  // POSIX unicode extensions.
647
1.34k
  
case CArg: return "C"19
;
648
1.34k
  
case SArg: return "S"27
;
649
1.34k
650
1.34k
  // Objective-C specific specifiers.
651
1.34k
  
case ObjCObjArg: return "@"26
;
652
1.34k
653
1.34k
  // FreeBSD kernel specific specifiers.
654
1.34k
  
case FreeBSDbArg: return "b"0
;
655
1.34k
  
case FreeBSDDArg: return "D"0
;
656
1.34k
  
case FreeBSDrArg: return "r"27
;
657
1.34k
  
case FreeBSDyArg: return "y"27
;
658
1.34k
659
1.34k
  // GlibC specific specifiers.
660
1.34k
  
case PrintErrno: return "m"0
;
661
1.34k
662
1.34k
  // MS specific specifiers.
663
1.34k
  
case ZArg: return "Z"7
;
664
0
  }
665
0
  return nullptr;
666
0
}
667
668
Optional<ConversionSpecifier>
669
149
ConversionSpecifier::getStandardSpecifier() const {
670
149
  ConversionSpecifier::Kind NewKind;
671
149
672
149
  switch (getKind()) {
673
149
  default:
674
88
    return None;
675
149
  case DArg:
676
25
    NewKind = dArg;
677
25
    break;
678
149
  case UArg:
679
18
    NewKind = uArg;
680
18
    break;
681
149
  case OArg:
682
18
    NewKind = oArg;
683
18
    break;
684
61
  }
685
61
686
61
  ConversionSpecifier FixedCS(*this);
687
61
  FixedCS.setKind(NewKind);
688
61
  return FixedCS;
689
61
}
690
691
//===----------------------------------------------------------------------===//
692
// Methods on OptionalAmount.
693
//===----------------------------------------------------------------------===//
694
695
1.76k
void OptionalAmount::toString(raw_ostream &os) const {
696
1.76k
  switch (hs) {
697
1.76k
  case Invalid:
698
1.70k
  case NotSpecified:
699
1.70k
    return;
700
1.70k
  case Arg:
701
4
    if (UsesDotPrefix)
702
4
        os << ".";
703
4
    if (usesPositionalArg())
704
2
      os << "*" << getPositionalArgIndex() << "$";
705
2
    else
706
2
      os << "*";
707
4
    break;
708
1.70k
  case Constant:
709
52
    if (UsesDotPrefix)
710
11
        os << ".";
711
52
    os << amt;
712
52
    break;
713
1.76k
  }
714
1.76k
}
715
716
bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target,
717
57.7k
                                             const LangOptions &LO) const {
718
57.7k
  switch (LM.getKind()) {
719
57.7k
    case LengthModifier::None:
720
43.0k
      return true;
721
57.7k
722
57.7k
    // Handle most integer flags
723
57.7k
    case LengthModifier::AsShort:
724
1.13k
      // Length modifier only applies to FP vectors.
725
1.13k
      if (LO.OpenCL && 
CS.isDoubleArg()37
)
726
6
        return !VectorNumElts.isInvalid();
727
1.13k
728
1.13k
      if (Target.getTriple().isOSMSVCRT()) {
729
11
        switch (CS.getKind()) {
730
11
          case ConversionSpecifier::cArg:
731
9
          case ConversionSpecifier::CArg:
732
9
          case ConversionSpecifier::sArg:
733
9
          case ConversionSpecifier::SArg:
734
9
          case ConversionSpecifier::ZArg:
735
9
            return true;
736
9
          default:
737
2
            break;
738
1.12k
        }
739
1.12k
      }
740
1.12k
      LLVM_FALLTHROUGH;
741
12.6k
    case LengthModifier::AsChar:
742
12.6k
    case LengthModifier::AsLongLong:
743
12.6k
    case LengthModifier::AsQuad:
744
12.6k
    case LengthModifier::AsIntMax:
745
12.6k
    case LengthModifier::AsSizeT:
746
12.6k
    case LengthModifier::AsPtrDiff:
747
12.6k
      switch (CS.getKind()) {
748
12.6k
        case ConversionSpecifier::dArg:
749
12.5k
        case ConversionSpecifier::DArg:
750
12.5k
        case ConversionSpecifier::iArg:
751
12.5k
        case ConversionSpecifier::oArg:
752
12.5k
        case ConversionSpecifier::OArg:
753
12.5k
        case ConversionSpecifier::uArg:
754
12.5k
        case ConversionSpecifier::UArg:
755
12.5k
        case ConversionSpecifier::xArg:
756
12.5k
        case ConversionSpecifier::XArg:
757
12.5k
        case ConversionSpecifier::nArg:
758
12.5k
          return true;
759
12.5k
        case ConversionSpecifier::FreeBSDrArg:
760
12
        case ConversionSpecifier::FreeBSDyArg:
761
12
          return Target.getTriple().isOSFreeBSD() || 
Target.getTriple().isPS4()4
;
762
100
        default:
763
100
          return false;
764
0
      }
765
0
766
82
    case LengthModifier::AsShortLong:
767
82
      return LO.OpenCL && !VectorNumElts.isInvalid();
768
0
769
0
    // Handle 'l' flag
770
1.69k
    case LengthModifier::AsLong: // or AsWideChar
771
1.69k
      if (CS.isDoubleArg()) {
772
638
        // Invalid for OpenCL FP scalars.
773
638
        if (LO.OpenCL && 
VectorNumElts.isInvalid()29
)
774
1
          return false;
775
637
        return true;
776
637
      }
777
1.05k
778
1.05k
      switch (CS.getKind()) {
779
1.05k
        case ConversionSpecifier::dArg:
780
1.02k
        case ConversionSpecifier::DArg:
781
1.02k
        case ConversionSpecifier::iArg:
782
1.02k
        case ConversionSpecifier::oArg:
783
1.02k
        case ConversionSpecifier::OArg:
784
1.02k
        case ConversionSpecifier::uArg:
785
1.02k
        case ConversionSpecifier::UArg:
786
1.02k
        case ConversionSpecifier::xArg:
787
1.02k
        case ConversionSpecifier::XArg:
788
1.02k
        case ConversionSpecifier::nArg:
789
1.02k
        case ConversionSpecifier::cArg:
790
1.02k
        case ConversionSpecifier::sArg:
791
1.02k
        case ConversionSpecifier::ScanListArg:
792
1.02k
        case ConversionSpecifier::ZArg:
793
1.02k
          return true;
794
1.02k
        case ConversionSpecifier::FreeBSDrArg:
795
18
        case ConversionSpecifier::FreeBSDyArg:
796
18
          return Target.getTriple().isOSFreeBSD() || 
Target.getTriple().isPS4()6
;
797
18
        default:
798
8
          return false;
799
0
      }
800
0
801
115
    case LengthModifier::AsLongDouble:
802
115
      switch (CS.getKind()) {
803
115
        case ConversionSpecifier::aArg:
804
54
        case ConversionSpecifier::AArg:
805
54
        case ConversionSpecifier::fArg:
806
54
        case ConversionSpecifier::FArg:
807
54
        case ConversionSpecifier::eArg:
808
54
        case ConversionSpecifier::EArg:
809
54
        case ConversionSpecifier::gArg:
810
54
        case ConversionSpecifier::GArg:
811
54
          return true;
812
54
        // GNU libc extension.
813
54
        case ConversionSpecifier::dArg:
814
43
        case ConversionSpecifier::iArg:
815
43
        case ConversionSpecifier::oArg:
816
43
        case ConversionSpecifier::uArg:
817
43
        case ConversionSpecifier::xArg:
818
43
        case ConversionSpecifier::XArg:
819
43
          return !Target.getTriple().isOSDarwin() &&
820
43
                 
!Target.getTriple().isOSWindows()37
;
821
43
        default:
822
18
          return false;
823
0
      }
824
0
825
6
    case LengthModifier::AsAllocate:
826
6
      switch (CS.getKind()) {
827
6
        case ConversionSpecifier::sArg:
828
6
        case ConversionSpecifier::SArg:
829
6
        case ConversionSpecifier::ScanListArg:
830
6
          return true;
831
6
        default:
832
0
          return false;
833
0
      }
834
0
835
23
    case LengthModifier::AsMAllocate:
836
23
      switch (CS.getKind()) {
837
23
        case ConversionSpecifier::cArg:
838
21
        case ConversionSpecifier::CArg:
839
21
        case ConversionSpecifier::sArg:
840
21
        case ConversionSpecifier::SArg:
841
21
        case ConversionSpecifier::ScanListArg:
842
21
          return true;
843
21
        default:
844
2
          return false;
845
0
      }
846
11
    case LengthModifier::AsInt32:
847
11
    case LengthModifier::AsInt3264:
848
11
    case LengthModifier::AsInt64:
849
11
      switch (CS.getKind()) {
850
11
        case ConversionSpecifier::dArg:
851
11
        case ConversionSpecifier::iArg:
852
11
        case ConversionSpecifier::oArg:
853
11
        case ConversionSpecifier::uArg:
854
11
        case ConversionSpecifier::xArg:
855
11
        case ConversionSpecifier::XArg:
856
11
          return Target.getTriple().isOSMSVCRT();
857
11
        default:
858
0
          return false;
859
0
      }
860
18
    case LengthModifier::AsWide:
861
18
      switch (CS.getKind()) {
862
18
        case ConversionSpecifier::cArg:
863
18
        case ConversionSpecifier::CArg:
864
18
        case ConversionSpecifier::sArg:
865
18
        case ConversionSpecifier::SArg:
866
18
        case ConversionSpecifier::ZArg:
867
18
          return Target.getTriple().isOSMSVCRT();
868
18
        default:
869
0
          return false;
870
0
      }
871
0
  }
872
0
  llvm_unreachable("Invalid LengthModifier Kind!");
873
0
}
874
875
56.8k
bool FormatSpecifier::hasStandardLengthModifier() const {
876
56.8k
  switch (LM.getKind()) {
877
56.8k
    case LengthModifier::None:
878
56.7k
    case LengthModifier::AsChar:
879
56.7k
    case LengthModifier::AsShort:
880
56.7k
    case LengthModifier::AsLong:
881
56.7k
    case LengthModifier::AsLongLong:
882
56.7k
    case LengthModifier::AsIntMax:
883
56.7k
    case LengthModifier::AsSizeT:
884
56.7k
    case LengthModifier::AsPtrDiff:
885
56.7k
    case LengthModifier::AsLongDouble:
886
56.7k
      return true;
887
56.7k
    case LengthModifier::AsAllocate:
888
114
    case LengthModifier::AsMAllocate:
889
114
    case LengthModifier::AsQuad:
890
114
    case LengthModifier::AsInt32:
891
114
    case LengthModifier::AsInt3264:
892
114
    case LengthModifier::AsInt64:
893
114
    case LengthModifier::AsWide:
894
114
    case LengthModifier::AsShortLong: // ???
895
114
      return false;
896
0
  }
897
0
  llvm_unreachable("Invalid LengthModifier Kind!");
898
0
}
899
900
bool FormatSpecifier::hasStandardConversionSpecifier(
901
56.9k
    const LangOptions &LangOpt) const {
902
56.9k
  switch (CS.getKind()) {
903
56.9k
    case ConversionSpecifier::cArg:
904
56.7k
    case ConversionSpecifier::dArg:
905
56.7k
    case ConversionSpecifier::iArg:
906
56.7k
    case ConversionSpecifier::oArg:
907
56.7k
    case ConversionSpecifier::uArg:
908
56.7k
    case ConversionSpecifier::xArg:
909
56.7k
    case ConversionSpecifier::XArg:
910
56.7k
    case ConversionSpecifier::fArg:
911
56.7k
    case ConversionSpecifier::FArg:
912
56.7k
    case ConversionSpecifier::eArg:
913
56.7k
    case ConversionSpecifier::EArg:
914
56.7k
    case ConversionSpecifier::gArg:
915
56.7k
    case ConversionSpecifier::GArg:
916
56.7k
    case ConversionSpecifier::aArg:
917
56.7k
    case ConversionSpecifier::AArg:
918
56.7k
    case ConversionSpecifier::sArg:
919
56.7k
    case ConversionSpecifier::pArg:
920
56.7k
    case ConversionSpecifier::nArg:
921
56.7k
    case ConversionSpecifier::ObjCObjArg:
922
56.7k
    case ConversionSpecifier::ScanListArg:
923
56.7k
    case ConversionSpecifier::PercentArg:
924
56.7k
    case ConversionSpecifier::PArg:
925
56.7k
      return true;
926
56.7k
    case ConversionSpecifier::CArg:
927
82
    case ConversionSpecifier::SArg:
928
82
      return LangOpt.ObjC;
929
103
    case ConversionSpecifier::InvalidSpecifier:
930
103
    case ConversionSpecifier::FreeBSDbArg:
931
103
    case ConversionSpecifier::FreeBSDDArg:
932
103
    case ConversionSpecifier::FreeBSDrArg:
933
103
    case ConversionSpecifier::FreeBSDyArg:
934
103
    case ConversionSpecifier::PrintErrno:
935
103
    case ConversionSpecifier::DArg:
936
103
    case ConversionSpecifier::OArg:
937
103
    case ConversionSpecifier::UArg:
938
103
    case ConversionSpecifier::ZArg:
939
103
      return false;
940
0
  }
941
0
  llvm_unreachable("Invalid ConversionSpecifier Kind!");
942
0
}
943
944
56.7k
bool FormatSpecifier::hasStandardLengthConversionCombination() const {
945
56.7k
  if (LM.getKind() == LengthModifier::AsLongDouble) {
946
69
    switch(CS.getKind()) {
947
69
        case ConversionSpecifier::dArg:
948
33
        case ConversionSpecifier::iArg:
949
33
        case ConversionSpecifier::oArg:
950
33
        case ConversionSpecifier::uArg:
951
33
        case ConversionSpecifier::xArg:
952
33
        case ConversionSpecifier::XArg:
953
33
          return false;
954
36
        default:
955
36
          return true;
956
56.6k
    }
957
56.6k
  }
958
56.6k
  return true;
959
56.6k
}
960
961
203
Optional<LengthModifier> FormatSpecifier::getCorrectedLengthModifier() const {
962
203
  if (CS.isAnyIntArg() || 
CS.getKind() == ConversionSpecifier::nArg109
) {
963
108
    if (LM.getKind() == LengthModifier::AsLongDouble ||
964
108
        
LM.getKind() == LengthModifier::AsQuad65
) {
965
65
      LengthModifier FixedLM(LM);
966
65
      FixedLM.setKind(LengthModifier::AsLongLong);
967
65
      return FixedLM;
968
65
    }
969
138
  }
970
138
971
138
  return None;
972
138
}
973
974
bool FormatSpecifier::namedTypeToLengthModifier(QualType QT,
975
101
                                                LengthModifier &LM) {
976
101
  assert(isa<TypedefType>(QT) && "Expected a TypedefType");
977
101
  const TypedefNameDecl *Typedef = cast<TypedefType>(QT)->getDecl();
978
101
979
119
  for (;;) {
980
119
    const IdentifierInfo *Identifier = Typedef->getIdentifier();
981
119
    if (Identifier->getName() == "size_t") {
982
23
      LM.setKind(LengthModifier::AsSizeT);
983
23
      return true;
984
96
    } else if (Identifier->getName() == "ssize_t") {
985
8
      // Not C99, but common in Unix.
986
8
      LM.setKind(LengthModifier::AsSizeT);
987
8
      return true;
988
88
    } else if (Identifier->getName() == "intmax_t") {
989
4
      LM.setKind(LengthModifier::AsIntMax);
990
4
      return true;
991
84
    } else if (Identifier->getName() == "uintmax_t") {
992
4
      LM.setKind(LengthModifier::AsIntMax);
993
4
      return true;
994
80
    } else if (Identifier->getName() == "ptrdiff_t") {
995
4
      LM.setKind(LengthModifier::AsPtrDiff);
996
4
      return true;
997
4
    }
998
76
999
76
    QualType T = Typedef->getUnderlyingType();
1000
76
    if (!isa<TypedefType>(T))
1001
58
      break;
1002
18
1003
18
    Typedef = cast<TypedefType>(T)->getDecl();
1004
18
  }
1005
101
  
return false58
;
1006
101
}