diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2018-12-11 19:18:01 +0000 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2018-12-11 19:18:01 +0000 |
commit | 078643e63df5dabfe1d77f77f8c20a929aefeee6 (patch) | |
tree | 54e9eb6d92e0039171f14660e97632ffa393c602 /clang/lib/Sema/SemaChecking.cpp | |
parent | 8ec89e6b161e3063bba6351289f36ecc61e6beab (diff) | |
download | llvm-078643e63df5dabfe1d77f77f8c20a929aefeee6.zip llvm-078643e63df5dabfe1d77f77f8c20a929aefeee6.tar.gz llvm-078643e63df5dabfe1d77f77f8c20a929aefeee6.tar.bz2 |
Emit -Wformat properly for bit-field promotions.
Only explicitly look through integer and floating-point promotion where the result type is actually a promotion, which is not always the case for bit-fields in C.
llvm-svn: 348889
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 9fed476..b54bcd8 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -7709,6 +7709,24 @@ shouldNotPrintDirectly(const ASTContext &Context, return std::make_pair(QualType(), StringRef()); } +/// Return true if \p ICE is an implicit argument promotion of an arithmetic +/// type. Bit-field 'promotions' from a higher ranked type to a lower ranked +/// type do not count. +static bool +isArithmeticArgumentPromotion(Sema &S, const ImplicitCastExpr *ICE) { + QualType From = ICE->getSubExpr()->getType(); + QualType To = ICE->getType(); + // It's a floating promotion if the source type is a lower rank. + if (ICE->getCastKind() == CK_FloatingCast && + S.Context.getFloatingTypeOrder(From, To) < 0) + return true; + // It's an integer promotion if the destination type is the promoted + // source type. + return ICE->getCastKind() == CK_IntegralCast && + From->isPromotableIntegerType() && + S.Context.getPromotedIntegerType(From) == To; +} + bool CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, const char *StartSpecifier, @@ -7736,11 +7754,11 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS, // Look through argument promotions for our error message's reported type. // This includes the integral and floating promotions, but excludes array - // and function pointer decay; seeing that an argument intended to be a - // string has type 'char [6]' is probably more confusing than 'char *'. + // and function pointer decay (seeing that an argument intended to be a + // string has type 'char [6]' is probably more confusing than 'char *') and + // certain bitfield promotions (bitfields can be 'demoted' to a lesser type). if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) { - if (ICE->getCastKind() == CK_IntegralCast || - ICE->getCastKind() == CK_FloatingCast) { + if (isArithmeticArgumentPromotion(S, ICE)) { E = ICE->getSubExpr(); ExprTy = E->getType(); |