forked from OSchip/llvm-project
MS format strings: parse the 'Z' printf conversion specifier (PR20808)
llvm-svn: 217326
This commit is contained in:
parent
69abd72e49
commit
c597b4c529
|
@ -155,6 +155,8 @@ public:
|
|||
|
||||
// ** Printf-specific **
|
||||
|
||||
ZArg, // MS extension
|
||||
|
||||
// Objective-C specific specifiers.
|
||||
ObjCObjArg, // '@'
|
||||
ObjCBeg = ObjCObjArg, ObjCEnd = ObjCObjArg,
|
||||
|
|
|
@ -554,6 +554,9 @@ const char *ConversionSpecifier::toString() const {
|
|||
|
||||
// GlibC specific specifiers.
|
||||
case PrintErrno: return "m";
|
||||
|
||||
// MS specific specifiers.
|
||||
case ZArg: return "Z";
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -619,6 +622,7 @@ bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const {
|
|||
case ConversionSpecifier::CArg:
|
||||
case ConversionSpecifier::sArg:
|
||||
case ConversionSpecifier::SArg:
|
||||
case ConversionSpecifier::ZArg:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
|
@ -671,6 +675,7 @@ bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const {
|
|||
case ConversionSpecifier::cArg:
|
||||
case ConversionSpecifier::sArg:
|
||||
case ConversionSpecifier::ScanListArg:
|
||||
case ConversionSpecifier::ZArg:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
@ -740,7 +745,8 @@ bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const {
|
|||
case ConversionSpecifier::cArg:
|
||||
case ConversionSpecifier::CArg:
|
||||
case ConversionSpecifier::sArg:
|
||||
case ConversionSpecifier::SArg: // FIXME: Or Z.
|
||||
case ConversionSpecifier::SArg:
|
||||
case ConversionSpecifier::ZArg:
|
||||
return Target.getTriple().isOSMSVCRT();
|
||||
default:
|
||||
return false;
|
||||
|
@ -805,6 +811,7 @@ bool FormatSpecifier::hasStandardConversionSpecifier(const LangOptions &LangOpt)
|
|||
case ConversionSpecifier::DArg:
|
||||
case ConversionSpecifier::OArg:
|
||||
case ConversionSpecifier::UArg:
|
||||
case ConversionSpecifier::ZArg:
|
||||
return false;
|
||||
}
|
||||
llvm_unreachable("Invalid ConversionSpecifier Kind!");
|
||||
|
|
|
@ -198,7 +198,7 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
|
|||
case '@': k = ConversionSpecifier::ObjCObjArg; break;
|
||||
// Glibc specific.
|
||||
case 'm': k = ConversionSpecifier::PrintErrno; break;
|
||||
// Apple-specific
|
||||
// Apple-specific.
|
||||
case 'D':
|
||||
if (Target.getTriple().isOSDarwin())
|
||||
k = ConversionSpecifier::DArg;
|
||||
|
@ -211,6 +211,10 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
|
|||
if (Target.getTriple().isOSDarwin())
|
||||
k = ConversionSpecifier::UArg;
|
||||
break;
|
||||
// MS specific.
|
||||
case 'Z':
|
||||
if (Target.getTriple().isOSMSVCRT())
|
||||
k = ConversionSpecifier::ZArg;
|
||||
}
|
||||
PrintfConversionSpecifier CS(conversionPosition, k);
|
||||
FS.setConversionSpecifier(CS);
|
||||
|
|
|
@ -8,11 +8,12 @@ typedef unsigned short wchar_t;
|
|||
#ifdef NON_ISO_WARNING
|
||||
|
||||
// Split off this test to reduce the warning noise in the rest of the file.
|
||||
void non_iso_warning_test(__int32 i32, __int64 i64, wchar_t c) {
|
||||
void non_iso_warning_test(__int32 i32, __int64 i64, wchar_t c, void *p) {
|
||||
printf("%Id", i32); // expected-warning{{'I' length modifier is not supported by ISO C}}
|
||||
printf("%I32d", i32); // expected-warning{{'I32' length modifier is not supported by ISO C}}
|
||||
printf("%I64d", i64); // expected-warning{{'I64' length modifier is not supported by ISO C}}
|
||||
printf("%wc", c); // expected-warning{{'w' length modifier is not supported by ISO C}}
|
||||
printf("%Z", p); // expected-warning{{'Z' conversion specifier is not supported by ISO C}}
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -75,4 +76,13 @@ void h_test(char c, char* s) {
|
|||
scanf("%hS", &bad); // expected-warning{{format specifies type 'char *' but the argument has type 'double *'}}
|
||||
}
|
||||
|
||||
void z_test(void *p) {
|
||||
printf("%Z", p);
|
||||
printf("%hZ", p);
|
||||
printf("%lZ", p);
|
||||
printf("%wZ", p);
|
||||
printf("%hhZ", p); // expected-warning{{length modifier 'hh' results in undefined behavior or no effect with 'Z' conversion specifier}}
|
||||
scanf("%Z", p); // expected-warning{{invalid conversion specifier 'Z'}}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue