@@ -12446,6 +12446,19 @@ isArithmeticArgumentPromotion(Sema &S, const ImplicitCastExpr *ICE) {
1244612446 S.Context.getFloatingTypeOrder(From, To) < 0;
1244712447}
1244812448
12449+ static analyze_format_string::ArgType::MatchKind
12450+ handleFormatSignedness(analyze_format_string::ArgType::MatchKind Match,
12451+ DiagnosticsEngine &Diags, SourceLocation Loc) {
12452+ if (Match == analyze_format_string::ArgType::NoMatchSignedness) {
12453+ Match =
12454+ Diags.isIgnored(
12455+ diag::warn_format_conversion_argument_type_mismatch_signedness, Loc)
12456+ ? analyze_format_string::ArgType::Match
12457+ : analyze_format_string::ArgType::NoMatch;
12458+ }
12459+ return Match;
12460+ }
12461+
1244912462bool
1245012463CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
1245112464 const char *StartSpecifier,
@@ -12489,6 +12502,9 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
1248912502
1249012503 ArgType::MatchKind ImplicitMatch = ArgType::NoMatch;
1249112504 ArgType::MatchKind Match = AT.matchesType(S.Context, ExprTy);
12505+ ArgType::MatchKind OrigMatch = Match;
12506+
12507+ Match = handleFormatSignedness(Match, S.getDiagnostics(), E->getExprLoc());
1249212508 if (Match == ArgType::Match)
1249312509 return true;
1249412510
@@ -12512,6 +12528,14 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
1251212528 ICE->getType() == S.Context.UnsignedIntTy) {
1251312529 // All further checking is done on the subexpression
1251412530 ImplicitMatch = AT.matchesType(S.Context, ExprTy);
12531+ if (OrigMatch == ArgType::NoMatchSignedness &&
12532+ ImplicitMatch != ArgType::NoMatchSignedness)
12533+ // If the original match was a signedness match this match on the
12534+ // implicit cast type also need to be signedness match otherwise we
12535+ // might introduce new unexpected warnings from -Wformat-signedness.
12536+ return true;
12537+ ImplicitMatch = handleFormatSignedness(
12538+ ImplicitMatch, S.getDiagnostics(), E->getExprLoc());
1251512539 if (ImplicitMatch == ArgType::Match)
1251612540 return true;
1251712541 }
@@ -12633,6 +12657,7 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
1263312657 case ArgType::Match:
1263412658 case ArgType::MatchPromotion:
1263512659 case ArgType::NoMatchPromotionTypeConfusion:
12660+ case ArgType::NoMatchSignedness:
1263612661 llvm_unreachable("expected non-matching");
1263712662 case ArgType::NoMatchPedantic:
1263812663 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
@@ -12668,8 +12693,10 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
1266812693 CastFix << (S.LangOpts.CPlusPlus ? ">" : ")");
1266912694
1267012695 SmallVector<FixItHint,4> Hints;
12671- if (AT.matchesType(S.Context, IntendedTy) != ArgType::Match ||
12672- ShouldNotPrintDirectly)
12696+ ArgType::MatchKind IntendedMatch = AT.matchesType(S.Context, IntendedTy);
12697+ IntendedMatch = handleFormatSignedness(IntendedMatch, S.getDiagnostics(),
12698+ E->getExprLoc());
12699+ if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
1267312700 Hints.push_back(FixItHint::CreateReplacement(SpecRange, os.str()));
1267412701
1267512702 if (const CStyleCastExpr *CCast = dyn_cast<CStyleCastExpr>(E)) {
@@ -12738,6 +12765,7 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
1273812765 case ArgType::Match:
1273912766 case ArgType::MatchPromotion:
1274012767 case ArgType::NoMatchPromotionTypeConfusion:
12768+ case ArgType::NoMatchSignedness:
1274112769 llvm_unreachable("expected non-matching");
1274212770 case ArgType::NoMatchPedantic:
1274312771 Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
@@ -12949,6 +12977,7 @@ bool CheckScanfHandler::HandleScanfSpecifier(
1294912977
1295012978 analyze_format_string::ArgType::MatchKind Match =
1295112979 AT.matchesType(S.Context, Ex->getType());
12980+ Match = handleFormatSignedness(Match, S.getDiagnostics(), Ex->getExprLoc());
1295212981 bool Pedantic = Match == analyze_format_string::ArgType::NoMatchPedantic;
1295312982 if (Match == analyze_format_string::ArgType::Match)
1295412983 return true;
0 commit comments