mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-25 02:28:18 +00:00
Format string analysis: give 'q' its own enumerator.
This is in preparation for being able to warn about 'q' and other non-standard format string features. It also allows us to print its name correctly. llvm-svn: 150697
This commit is contained in:
parent
96de9933fb
commit
9bc9bcc247
@ -66,7 +66,8 @@ public:
|
||||
AsChar, // 'hh'
|
||||
AsShort, // 'h'
|
||||
AsLong, // 'l'
|
||||
AsLongLong, // 'll', 'q' (BSD, deprecated)
|
||||
AsLongLong, // 'll'
|
||||
AsQuad, // 'q' (BSD, deprecated, same as 'll')
|
||||
AsIntMax, // 'j'
|
||||
AsSizeT, // 'z'
|
||||
AsPtrDiff, // 't'
|
||||
|
@ -198,7 +198,7 @@ clang::analyze_format_string::ParseLengthModifier(FormatSpecifier &FS,
|
||||
case 'z': lmKind = LengthModifier::AsSizeT; ++I; break;
|
||||
case 't': lmKind = LengthModifier::AsPtrDiff; ++I; break;
|
||||
case 'L': lmKind = LengthModifier::AsLongDouble; ++I; break;
|
||||
case 'q': lmKind = LengthModifier::AsLongLong; ++I; break;
|
||||
case 'q': lmKind = LengthModifier::AsQuad; ++I; break;
|
||||
case 'a':
|
||||
if (IsScanf && !LO.C99 && !LO.CPlusPlus0x) {
|
||||
// For scanf in C90, look at the next character to see if this should
|
||||
@ -417,6 +417,8 @@ analyze_format_string::LengthModifier::toString() const {
|
||||
return "l";
|
||||
case AsLongLong:
|
||||
return "ll";
|
||||
case AsQuad:
|
||||
return "q";
|
||||
case AsIntMax:
|
||||
return "j";
|
||||
case AsSizeT:
|
||||
@ -506,10 +508,11 @@ bool FormatSpecifier::hasValidLengthModifier() const {
|
||||
case LengthModifier::None:
|
||||
return true;
|
||||
|
||||
// Handle most integer flags
|
||||
// Handle most integer flags
|
||||
case LengthModifier::AsChar:
|
||||
case LengthModifier::AsShort:
|
||||
case LengthModifier::AsLongLong:
|
||||
case LengthModifier::AsQuad:
|
||||
case LengthModifier::AsIntMax:
|
||||
case LengthModifier::AsSizeT:
|
||||
case LengthModifier::AsPtrDiff:
|
||||
@ -526,7 +529,7 @@ bool FormatSpecifier::hasValidLengthModifier() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Handle 'l' flag
|
||||
// Handle 'l' flag
|
||||
case LengthModifier::AsLong:
|
||||
switch (CS.getKind()) {
|
||||
case ConversionSpecifier::dArg:
|
||||
|
@ -266,7 +266,9 @@ ArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx,
|
||||
case LengthModifier::AsChar: return ArgTypeResult::AnyCharTy;
|
||||
case LengthModifier::AsShort: return Ctx.ShortTy;
|
||||
case LengthModifier::AsLong: return Ctx.LongTy;
|
||||
case LengthModifier::AsLongLong: return Ctx.LongLongTy;
|
||||
case LengthModifier::AsLongLong:
|
||||
case LengthModifier::AsQuad:
|
||||
return Ctx.LongLongTy;
|
||||
case LengthModifier::AsIntMax:
|
||||
return ArgTypeResult(Ctx.getIntMaxType(), "intmax_t");
|
||||
case LengthModifier::AsSizeT:
|
||||
@ -288,7 +290,9 @@ ArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx,
|
||||
case LengthModifier::AsChar: return Ctx.UnsignedCharTy;
|
||||
case LengthModifier::AsShort: return Ctx.UnsignedShortTy;
|
||||
case LengthModifier::AsLong: return Ctx.UnsignedLongTy;
|
||||
case LengthModifier::AsLongLong: return Ctx.UnsignedLongLongTy;
|
||||
case LengthModifier::AsLongLong:
|
||||
case LengthModifier::AsQuad:
|
||||
return Ctx.UnsignedLongLongTy;
|
||||
case LengthModifier::AsIntMax:
|
||||
return ArgTypeResult(Ctx.getUIntMaxType(), "uintmax_t");
|
||||
case LengthModifier::AsSizeT:
|
||||
|
@ -210,7 +210,9 @@ ScanfArgTypeResult ScanfSpecifier::getArgType(ASTContext &Ctx) const {
|
||||
return ArgTypeResult(ArgTypeResult::AnyCharTy);
|
||||
case LengthModifier::AsShort: return ArgTypeResult(Ctx.ShortTy);
|
||||
case LengthModifier::AsLong: return ArgTypeResult(Ctx.LongTy);
|
||||
case LengthModifier::AsLongLong: return ArgTypeResult(Ctx.LongLongTy);
|
||||
case LengthModifier::AsLongLong:
|
||||
case LengthModifier::AsQuad:
|
||||
return ArgTypeResult(Ctx.LongLongTy);
|
||||
case LengthModifier::AsIntMax:
|
||||
return ScanfArgTypeResult(Ctx.getIntMaxType(), "intmax_t *");
|
||||
case LengthModifier::AsSizeT:
|
||||
@ -236,6 +238,7 @@ ScanfArgTypeResult ScanfSpecifier::getArgType(ASTContext &Ctx) const {
|
||||
case LengthModifier::AsShort: return ArgTypeResult(Ctx.UnsignedShortTy);
|
||||
case LengthModifier::AsLong: return ArgTypeResult(Ctx.UnsignedLongTy);
|
||||
case LengthModifier::AsLongLong:
|
||||
case LengthModifier::AsQuad:
|
||||
return ArgTypeResult(Ctx.UnsignedLongLongTy);
|
||||
case LengthModifier::AsIntMax:
|
||||
return ScanfArgTypeResult(Ctx.getUIntMaxType(), "uintmax_t *");
|
||||
|
@ -117,3 +117,7 @@ void test_longlong(long long *x, unsigned long long *y) {
|
||||
scanf("%Ls", "hello"); // expected-warning {{length modifier 'L' results in undefined behavior or no effect with 's' conversion specifier}}
|
||||
}
|
||||
|
||||
void test_quad(int *x, long long *llx) {
|
||||
scanf("%qd", x); // expected-warning{{format specifies type 'long long *' but the argument has type 'int *'}}
|
||||
scanf("%qd", llx); // no-warning
|
||||
}
|
||||
|
@ -167,7 +167,9 @@ void test10(int x, float f, int i, long long lli) {
|
||||
printf("%.d", x); // no-warning
|
||||
printf("%.", x); // expected-warning{{incomplete format specifier}}
|
||||
printf("%f", 4); // expected-warning{{format specifies type 'double' but the argument has type 'int'}}
|
||||
printf("%qd", lli);
|
||||
printf("%qd", lli); // no-warning
|
||||
printf("%qd", x); // expected-warning{{format specifies type 'long long' but the argument has type 'int'}}
|
||||
printf("%qp", (void *)0); // expected-warning{{length modifier 'q' results in undefined behavior or no effect with 'p' conversion specifier}}
|
||||
printf("hhX %hhX", (unsigned char)10); // no-warning
|
||||
printf("llX %llX", (long long) 10); // no-warning
|
||||
// This is fine, because there is an implicit conversion to an int.
|
||||
|
Loading…
x
Reference in New Issue
Block a user