aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
authorAaron Ballman <aaron@aaronballman.com>2018-12-11 19:18:01 +0000
committerAaron Ballman <aaron@aaronballman.com>2018-12-11 19:18:01 +0000
commit078643e63df5dabfe1d77f77f8c20a929aefeee6 (patch)
tree54e9eb6d92e0039171f14660e97632ffa393c602 /clang/lib/Sema/SemaChecking.cpp
parent8ec89e6b161e3063bba6351289f36ecc61e6beab (diff)
downloadllvm-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.cpp26
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();