Skip to content

Commit

Permalink
[clang] Update -Wformat warnings for fixed-point format specifiers (#…
Browse files Browse the repository at this point in the history
…82855)

ISO/IEC TR 18037 defines %r, %R, %k, and %K for fixed point format
specifiers. -Wformat should not warn on these when they are provided.
  • Loading branch information
PiJoules committed Feb 27, 2024
1 parent 16e74fd commit 40ba1f6
Show file tree
Hide file tree
Showing 6 changed files with 306 additions and 3 deletions.
4 changes: 4 additions & 0 deletions clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -2981,6 +2981,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
// corresponding saturated type for a given fixed point type.
QualType getCorrespondingSaturatedType(QualType Ty) const;

// Per ISO N1169, this method accepts fixed point types and returns the
// corresponding non-saturated type for a given fixed point type.
QualType getCorrespondingUnsaturatedType(QualType Ty) const;

// This method accepts fixed point types and returns the corresponding signed
// type. Unlike getCorrespondingUnsignedType(), this only accepts unsigned
// fixed point types because there are unsigned integer types like bool and
Expand Down
11 changes: 11 additions & 0 deletions clang/include/clang/AST/FormatString.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,14 @@ class ConversionSpecifier {

ZArg, // MS extension

// ISO/IEC TR 18037 (fixed-point) specific specifiers.
kArg, // %k for signed accum types
KArg, // %K for unsigned accum types
rArg, // %r for signed fract types
RArg, // %R for unsigned fract types
FixedPointArgBeg = kArg,
FixedPointArgEnd = RArg,

// Objective-C specific specifiers.
ObjCObjArg, // '@'
ObjCBeg = ObjCObjArg,
Expand Down Expand Up @@ -237,6 +245,9 @@ class ConversionSpecifier {
bool isDoubleArg() const {
return kind >= DoubleArgBeg && kind <= DoubleArgEnd;
}
bool isFixedPointArg() const {
return kind >= FixedPointArgBeg && kind <= FixedPointArgEnd;
}

const char *toString() const;

Expand Down
36 changes: 36 additions & 0 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13314,6 +13314,42 @@ QualType ASTContext::getCommonSugaredType(QualType X, QualType Y,
return R;
}

QualType ASTContext::getCorrespondingUnsaturatedType(QualType Ty) const {
assert(Ty->isFixedPointType());

if (Ty->isUnsaturatedFixedPointType())
return Ty;

switch (Ty->castAs<BuiltinType>()->getKind()) {
default:
llvm_unreachable("Not a saturated fixed point type!");
case BuiltinType::SatShortAccum:
return ShortAccumTy;
case BuiltinType::SatAccum:
return AccumTy;
case BuiltinType::SatLongAccum:
return LongAccumTy;
case BuiltinType::SatUShortAccum:
return UnsignedShortAccumTy;
case BuiltinType::SatUAccum:
return UnsignedAccumTy;
case BuiltinType::SatULongAccum:
return UnsignedLongAccumTy;
case BuiltinType::SatShortFract:
return ShortFractTy;
case BuiltinType::SatFract:
return FractTy;
case BuiltinType::SatLongFract:
return LongFractTy;
case BuiltinType::SatUShortFract:
return UnsignedShortFractTy;
case BuiltinType::SatUFract:
return UnsignedFractTy;
case BuiltinType::SatULongFract:
return UnsignedLongFractTy;
}
}

QualType ASTContext::getCorrespondingSaturatedType(QualType Ty) const {
assert(Ty->isFixedPointType());

Expand Down
25 changes: 25 additions & 0 deletions clang/lib/AST/FormatString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,10 @@ ArgType::matchesType(ASTContext &C, QualType argTy) const {
else if (ETy->isUnscopedEnumerationType())
argTy = ETy->getDecl()->getIntegerType();
}

if (argTy->isSaturatedFixedPointType())
argTy = C.getCorrespondingUnsaturatedType(argTy);

argTy = C.getCanonicalType(argTy).getUnqualifiedType();

if (T == argTy)
Expand Down Expand Up @@ -761,6 +765,16 @@ const char *ConversionSpecifier::toString() const {

// MS specific specifiers.
case ZArg: return "Z";

// ISO/IEC TR 18037 (fixed-point) specific specifiers.
case rArg:
return "r";
case RArg:
return "R";
case kArg:
return "k";
case KArg:
return "K";
}
return nullptr;
}
Expand Down Expand Up @@ -825,6 +839,9 @@ bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target,
if (LO.OpenCL && CS.isDoubleArg())
return !VectorNumElts.isInvalid();

if (CS.isFixedPointArg())
return true;

if (Target.getTriple().isOSMSVCRT()) {
switch (CS.getKind()) {
case ConversionSpecifier::cArg:
Expand Down Expand Up @@ -877,6 +894,9 @@ bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target,
return true;
}

if (CS.isFixedPointArg())
return true;

switch (CS.getKind()) {
case ConversionSpecifier::bArg:
case ConversionSpecifier::BArg:
Expand Down Expand Up @@ -1043,6 +1063,11 @@ bool FormatSpecifier::hasStandardConversionSpecifier(
case ConversionSpecifier::UArg:
case ConversionSpecifier::ZArg:
return false;
case ConversionSpecifier::rArg:
case ConversionSpecifier::RArg:
case ConversionSpecifier::kArg:
case ConversionSpecifier::KArg:
return LangOpt.FixedPoint;
}
llvm_unreachable("Invalid ConversionSpecifier Kind!");
}
Expand Down
85 changes: 82 additions & 3 deletions clang/lib/AST/PrintfFormatString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,8 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
case 'r':
if (isFreeBSDKPrintf)
k = ConversionSpecifier::FreeBSDrArg; // int
else if (LO.FixedPoint)
k = ConversionSpecifier::rArg;
break;
case 'y':
if (isFreeBSDKPrintf)
Expand All @@ -373,6 +375,20 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
if (Target.getTriple().isOSMSVCRT())
k = ConversionSpecifier::ZArg;
break;
// ISO/IEC TR 18037 (fixed-point) specific.
// NOTE: 'r' is handled up above since FreeBSD also supports %r.
case 'k':
if (LO.FixedPoint)
k = ConversionSpecifier::kArg;
break;
case 'K':
if (LO.FixedPoint)
k = ConversionSpecifier::KArg;
break;
case 'R':
if (LO.FixedPoint)
k = ConversionSpecifier::RArg;
break;
}

// Check to see if we used the Objective-C modifier flags with
Expand Down Expand Up @@ -627,6 +643,9 @@ ArgType PrintfSpecifier::getScalarArgType(ASTContext &Ctx,
}
}

if (CS.isFixedPointArg() && !Ctx.getLangOpts().FixedPoint)
return ArgType::Invalid();

switch (CS.getKind()) {
case ConversionSpecifier::sArg:
if (LM.getKind() == LengthModifier::AsWideChar) {
Expand Down Expand Up @@ -658,6 +677,50 @@ ArgType PrintfSpecifier::getScalarArgType(ASTContext &Ctx,
return ArgType::CPointerTy;
case ConversionSpecifier::ObjCObjArg:
return ArgType::ObjCPointerTy;
case ConversionSpecifier::kArg:
switch (LM.getKind()) {
case LengthModifier::None:
return Ctx.AccumTy;
case LengthModifier::AsShort:
return Ctx.ShortAccumTy;
case LengthModifier::AsLong:
return Ctx.LongAccumTy;
default:
return ArgType::Invalid();
}
case ConversionSpecifier::KArg:
switch (LM.getKind()) {
case LengthModifier::None:
return Ctx.UnsignedAccumTy;
case LengthModifier::AsShort:
return Ctx.UnsignedShortAccumTy;
case LengthModifier::AsLong:
return Ctx.UnsignedLongAccumTy;
default:
return ArgType::Invalid();
}
case ConversionSpecifier::rArg:
switch (LM.getKind()) {
case LengthModifier::None:
return Ctx.FractTy;
case LengthModifier::AsShort:
return Ctx.ShortFractTy;
case LengthModifier::AsLong:
return Ctx.LongFractTy;
default:
return ArgType::Invalid();
}
case ConversionSpecifier::RArg:
switch (LM.getKind()) {
case LengthModifier::None:
return Ctx.UnsignedFractTy;
case LengthModifier::AsShort:
return Ctx.UnsignedShortFractTy;
case LengthModifier::AsLong:
return Ctx.UnsignedLongFractTy;
default:
return ArgType::Invalid();
}
default:
break;
}
Expand Down Expand Up @@ -955,6 +1018,8 @@ bool PrintfSpecifier::hasValidPlusPrefix() const {
case ConversionSpecifier::AArg:
case ConversionSpecifier::FreeBSDrArg:
case ConversionSpecifier::FreeBSDyArg:
case ConversionSpecifier::rArg:
case ConversionSpecifier::kArg:
return true;

default:
Expand All @@ -966,7 +1031,7 @@ bool PrintfSpecifier::hasValidAlternativeForm() const {
if (!HasAlternativeForm)
return true;

// Alternate form flag only valid with the bBoxXaAeEfFgG conversions
// Alternate form flag only valid with the bBoxXaAeEfFgGrRkK conversions
switch (CS.getKind()) {
case ConversionSpecifier::bArg:
case ConversionSpecifier::BArg:
Expand All @@ -984,6 +1049,10 @@ bool PrintfSpecifier::hasValidAlternativeForm() const {
case ConversionSpecifier::GArg:
case ConversionSpecifier::FreeBSDrArg:
case ConversionSpecifier::FreeBSDyArg:
case ConversionSpecifier::rArg:
case ConversionSpecifier::RArg:
case ConversionSpecifier::kArg:
case ConversionSpecifier::KArg:
return true;

default:
Expand All @@ -995,7 +1064,7 @@ bool PrintfSpecifier::hasValidLeadingZeros() const {
if (!HasLeadingZeroes)
return true;

// Leading zeroes flag only valid with the bBdiouxXaAeEfFgG conversions
// Leading zeroes flag only valid with the bBdiouxXaAeEfFgGrRkK conversions
switch (CS.getKind()) {
case ConversionSpecifier::bArg:
case ConversionSpecifier::BArg:
Expand All @@ -1018,6 +1087,10 @@ bool PrintfSpecifier::hasValidLeadingZeros() const {
case ConversionSpecifier::GArg:
case ConversionSpecifier::FreeBSDrArg:
case ConversionSpecifier::FreeBSDyArg:
case ConversionSpecifier::rArg:
case ConversionSpecifier::RArg:
case ConversionSpecifier::kArg:
case ConversionSpecifier::KArg:
return true;

default:
Expand All @@ -1044,6 +1117,8 @@ bool PrintfSpecifier::hasValidSpacePrefix() const {
case ConversionSpecifier::AArg:
case ConversionSpecifier::FreeBSDrArg:
case ConversionSpecifier::FreeBSDyArg:
case ConversionSpecifier::rArg:
case ConversionSpecifier::kArg:
return true;

default:
Expand Down Expand Up @@ -1089,7 +1164,7 @@ bool PrintfSpecifier::hasValidPrecision() const {
if (Precision.getHowSpecified() == OptionalAmount::NotSpecified)
return true;

// Precision is only valid with the bBdiouxXaAeEfFgGsP conversions
// Precision is only valid with the bBdiouxXaAeEfFgGsPrRkK conversions
switch (CS.getKind()) {
case ConversionSpecifier::bArg:
case ConversionSpecifier::BArg:
Expand All @@ -1114,6 +1189,10 @@ bool PrintfSpecifier::hasValidPrecision() const {
case ConversionSpecifier::FreeBSDrArg:
case ConversionSpecifier::FreeBSDyArg:
case ConversionSpecifier::PArg:
case ConversionSpecifier::rArg:
case ConversionSpecifier::RArg:
case ConversionSpecifier::kArg:
case ConversionSpecifier::KArg:
return true;

default:
Expand Down

0 comments on commit 40ba1f6

Please sign in to comment.