From 58fc8082a89f51a7cec210fa57c301bcb754aef0 Mon Sep 17 00:00:00 2001 From: Matt Arsenault Date: Tue, 29 Jan 2019 20:49:54 +0000 Subject: 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 --- clang/lib/AST/PrintfFormatString.cpp | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) (limited to 'clang/lib/AST/PrintfFormatString.cpp') 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: -- cgit v1.2.3