diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2019-01-29 20:49:54 +0000 |
---|---|---|
committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2019-01-29 20:49:54 +0000 |
commit | 58fc8082a89f51a7cec210fa57c301bcb754aef0 (patch) | |
tree | 97dfdac10ccd9f336e77f49ad32a2f93b2588e22 /clang/lib/AST | |
parent | 297afb14ec82180021aa1b2f02abd3c8c5e4c475 (diff) | |
download | bcm5719-llvm-58fc8082a89f51a7cec210fa57c301bcb754aef0.tar.gz bcm5719-llvm-58fc8082a89f51a7cec210fa57c301bcb754aef0.zip |
OpenCL: Use length modifier for warning on vector printf arguments
Re-enable format string warnings on printf.
The warnings are still incomplete. Apparently it is undefined to use a
vector specifier without a length modifier, which is not currently
warned on. Additionally, type warnings appear to not be working with
the hh modifier, and aren't warning on all of the special restrictions
from c99 printf.
llvm-svn: 352540
Diffstat (limited to 'clang/lib/AST')
-rw-r--r-- | clang/lib/AST/FormatString.cpp | 34 | ||||
-rw-r--r-- | clang/lib/AST/PrintfFormatString.cpp | 34 | ||||
-rw-r--r-- | clang/lib/AST/ScanfFormatString.cpp | 9 |
3 files changed, 59 insertions, 18 deletions
diff --git a/clang/lib/AST/FormatString.cpp b/clang/lib/AST/FormatString.cpp index e743e23078a..578d5bc5673 100644 --- a/clang/lib/AST/FormatString.cpp +++ b/clang/lib/AST/FormatString.cpp @@ -223,6 +223,9 @@ clang::analyze_format_string::ParseLengthModifier(FormatSpecifier &FS, if (I != E && *I == 'h') { ++I; lmKind = LengthModifier::AsChar; + } else if (I != E && *I == 'l' && LO.OpenCL) { + ++I; + lmKind = LengthModifier::AsShortLong; } else { lmKind = LengthModifier::AsShort; } @@ -487,7 +490,8 @@ ArgType::matchesType(ASTContext &C, QualType argTy) const { } ArgType ArgType::makeVectorType(ASTContext &C, unsigned NumElts) const { - if (K != SpecificTy) // Won't be a valid vector element type. + // Check for valid vector element types. + if (T.isNull()) return ArgType::Invalid(); QualType Vec = C.getExtVectorType(T, NumElts); @@ -572,6 +576,8 @@ analyze_format_string::LengthModifier::toString() const { return "hh"; case AsShort: return "h"; + case AsShortLong: + return "hl"; case AsLong: // or AsWideChar return "l"; case AsLongLong: @@ -707,13 +713,18 @@ void OptionalAmount::toString(raw_ostream &os) const { } } -bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const { +bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target, + const LangOptions &LO) const { switch (LM.getKind()) { case LengthModifier::None: return true; // Handle most integer flags case LengthModifier::AsShort: + // Length modifier only applies to FP vectors. + if (LO.OpenCL && CS.isDoubleArg()) + return !VectorNumElts.isInvalid(); + if (Target.getTriple().isOSMSVCRT()) { switch (CS.getKind()) { case ConversionSpecifier::cArg: @@ -752,8 +763,18 @@ bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const { return false; } + case LengthModifier::AsShortLong: + return LO.OpenCL && !VectorNumElts.isInvalid(); + // Handle 'l' flag case LengthModifier::AsLong: // or AsWideChar + if (CS.isDoubleArg()) { + // Invalid for OpenCL FP scalars. + if (LO.OpenCL && VectorNumElts.isInvalid()) + return false; + return true; + } + switch (CS.getKind()) { case ConversionSpecifier::dArg: case ConversionSpecifier::DArg: @@ -764,14 +785,6 @@ bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const { case ConversionSpecifier::UArg: case ConversionSpecifier::xArg: case ConversionSpecifier::XArg: - case ConversionSpecifier::aArg: - case ConversionSpecifier::AArg: - case ConversionSpecifier::fArg: - case ConversionSpecifier::FArg: - case ConversionSpecifier::eArg: - case ConversionSpecifier::EArg: - case ConversionSpecifier::gArg: - case ConversionSpecifier::GArg: case ConversionSpecifier::nArg: case ConversionSpecifier::cArg: case ConversionSpecifier::sArg: @@ -878,6 +891,7 @@ bool FormatSpecifier::hasStandardLengthModifier() const { case LengthModifier::AsInt3264: case LengthModifier::AsInt64: case LengthModifier::AsWide: + case LengthModifier::AsShortLong: // ??? return false; } llvm_unreachable("Invalid LengthModifier Kind!"); diff --git a/clang/lib/AST/PrintfFormatString.cpp b/clang/lib/AST/PrintfFormatString.cpp index df0a66456c3..a1207aae5aa 100644 --- a/clang/lib/AST/PrintfFormatString.cpp +++ b/clang/lib/AST/PrintfFormatString.cpp @@ -315,7 +315,11 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, case 'f': k = ConversionSpecifier::fArg; break; case 'g': k = ConversionSpecifier::gArg; break; case 'i': k = ConversionSpecifier::iArg; break; - case 'n': k = ConversionSpecifier::nArg; break; + case 'n': + // Not handled, but reserved in OpenCL. + if (!LO.OpenCL) + k = ConversionSpecifier::nArg; + break; case 'o': k = ConversionSpecifier::oArg; break; case 'p': k = ConversionSpecifier::pArg; break; case 's': k = ConversionSpecifier::sArg; break; @@ -486,10 +490,12 @@ ArgType PrintfSpecifier::getScalarArgType(ASTContext &Ctx, // GNU extension. return Ctx.LongLongTy; case LengthModifier::None: + case LengthModifier::AsShortLong: return Ctx.IntTy; case LengthModifier::AsInt32: return ArgType(Ctx.IntTy, "__int32"); - case LengthModifier::AsChar: return ArgType::AnyCharTy; + case LengthModifier::AsChar: + return ArgType::AnyCharTy; case LengthModifier::AsShort: return Ctx.ShortTy; case LengthModifier::AsLong: return Ctx.LongTy; case LengthModifier::AsLongLong: @@ -520,6 +526,7 @@ ArgType PrintfSpecifier::getScalarArgType(ASTContext &Ctx, // GNU extension. return Ctx.UnsignedLongLongTy; case LengthModifier::None: + case LengthModifier::AsShortLong: return Ctx.UnsignedIntTy; case LengthModifier::AsInt32: return ArgType(Ctx.UnsignedIntTy, "unsigned __int32"); @@ -549,6 +556,18 @@ ArgType PrintfSpecifier::getScalarArgType(ASTContext &Ctx, } if (CS.isDoubleArg()) { + if (!VectorNumElts.isInvalid()) { + switch (LM.getKind()) { + case LengthModifier::AsShort: + return Ctx.HalfTy; + case LengthModifier::AsShortLong: + return Ctx.FloatTy; + case LengthModifier::AsLong: + default: + return Ctx.DoubleTy; + } + } + if (LM.getKind() == LengthModifier::AsLongDouble) return Ctx.LongDoubleTy; return Ctx.DoubleTy; @@ -582,6 +601,8 @@ ArgType PrintfSpecifier::getScalarArgType(ASTContext &Ctx, case LengthModifier::AsInt64: case LengthModifier::AsWide: return ArgType::Invalid(); + case LengthModifier::AsShortLong: + llvm_unreachable("only used for OpenCL which doesn not handle nArg"); } } @@ -760,10 +781,13 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt, case BuiltinType::UInt: case BuiltinType::Int: case BuiltinType::Float: + LM.setKind(VectorNumElts.isInvalid() ? + LengthModifier::None : LengthModifier::AsShortLong); + break; case BuiltinType::Double: - LM.setKind(LengthModifier::None); + LM.setKind(VectorNumElts.isInvalid() ? + LengthModifier::None : LengthModifier::AsLong); break; - case BuiltinType::Char_U: case BuiltinType::UChar: case BuiltinType::Char_S: @@ -796,7 +820,7 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt, namedTypeToLengthModifier(QT, LM); // If fixing the length modifier was enough, we might be done. - if (hasValidLengthModifier(Ctx.getTargetInfo())) { + if (hasValidLengthModifier(Ctx.getTargetInfo(), LangOpt)) { // If we're going to offer a fix anyway, make sure the sign matches. switch (CS.getKind()) { case ConversionSpecifier::uArg: diff --git a/clang/lib/AST/ScanfFormatString.cpp b/clang/lib/AST/ScanfFormatString.cpp index ff4883305a7..1a87de70f86 100644 --- a/clang/lib/AST/ScanfFormatString.cpp +++ b/clang/lib/AST/ScanfFormatString.cpp @@ -261,9 +261,10 @@ ArgType ScanfSpecifier::getArgType(ASTContext &Ctx) const { case LengthModifier::AsInt32: case LengthModifier::AsInt3264: case LengthModifier::AsWide: + case LengthModifier::AsShortLong: return ArgType::Invalid(); } - llvm_unreachable("Unsupported LenghtModifier Type"); + llvm_unreachable("Unsupported LengthModifier Type"); // Unsigned int. case ConversionSpecifier::oArg: @@ -301,9 +302,10 @@ ArgType ScanfSpecifier::getArgType(ASTContext &Ctx) const { case LengthModifier::AsInt32: case LengthModifier::AsInt3264: case LengthModifier::AsWide: + case LengthModifier::AsShortLong: return ArgType::Invalid(); } - llvm_unreachable("Unsupported LenghtModifier Type"); + llvm_unreachable("Unsupported LengthModifier Type"); // Float. case ConversionSpecifier::aArg: @@ -396,6 +398,7 @@ ArgType ScanfSpecifier::getArgType(ASTContext &Ctx) const { case LengthModifier::AsInt32: case LengthModifier::AsInt3264: case LengthModifier::AsWide: + case LengthModifier::AsShortLong: return ArgType::Invalid(); } @@ -501,7 +504,7 @@ bool ScanfSpecifier::fixType(QualType QT, QualType RawQT, namedTypeToLengthModifier(PT, LM); // If fixing the length modifier was enough, we are done. - if (hasValidLengthModifier(Ctx.getTargetInfo())) { + if (hasValidLengthModifier(Ctx.getTargetInfo(), LangOpt)) { const analyze_scanf::ArgType &AT = getArgType(Ctx); if (AT.isValid() && AT.matchesType(Ctx, QT)) return true; |