================
@@ -7064,40 +7078,68 @@ static void CheckMissingFormatAttributes(Sema *S,
FormatStringType FormatType,
: 0;
break;
case Sema::FormatArgumentPassingKind::FAPK_Elsewhere:
- // Args are not passed to the callee.
- return;
+ // The callee has a format_matches attribute. We will emit that instead.
+ if (!ReferenceFormatString)
+ return;
+ break;
}
// Emit the diagnostic and fixit.
unsigned FormatStringIndex = CallerParamIdx + CallerArgumentIndexOffset;
StringRef FormatTypeName = S->GetFormatStringTypeName(FormatType);
- {
- std::string Attr =
- ("format(" + FormatTypeName + ", " + llvm::Twine(FormatStringIndex) +
- ", " + llvm::Twine(FirstArgumentIndex) + ")")
- .str();
+ do {
+ std::string Attr, Fixit;
+ if (APK != Sema::FormatArgumentPassingKind::FAPK_Elsewhere)
+ llvm::raw_string_ostream(Attr)
+ << "format(" << FormatTypeName << ", " << FormatStringIndex << ", "
+ << FirstArgumentIndex << ")";
+ else
+ llvm::raw_string_ostream(Attr)
+ << "format_matches(" << FormatTypeName << ", " << FormatStringIndex
+ << ", \"" << escapeFormatString(ReferenceFormatString->getString())
+ << "\")";
auto DB = S->Diag(Loc, diag::warn_missing_format_attribute)
<< Attr << Caller;
- const LangOptions &LO = S->getLangOpts();
- StringRef AttrPrefix, AttrSuffix;
- if (LO.C23 || LO.CPlusPlus11) {
- AttrPrefix = "[[gnu::";
- AttrSuffix = "]] ";
- } else if (LO.ObjC || LO.GNUMode) {
- AttrPrefix = "__attribute__((";
- AttrSuffix = ")) ";
+
+ SourceLocation SL;
+ llvm::raw_string_ostream IS(Fixit);
+ // The attribute goes at the start of the declaration in C/C++ functions
+ // and methods, but after the declaration for Objective-C methods.
+ if (isa<ObjCMethodDecl>(Caller)) {
+ IS << ' ';
+ SL = Caller->getEndLoc();
}
- if (!AttrPrefix.empty()) {
- DB << FixItHint::CreateInsertion(Caller->getBeginLoc(),
- (AttrPrefix + Attr + AttrSuffix).str());
+ const LangOptions &LO = S->getLangOpts();
+ if (LO.C23 || LO.CPlusPlus11)
+ IS << "[[gnu::" << Attr << "]]";
+ else if (LO.ObjC || LO.GNUMode)
+ IS << "__attribute__((" << Attr << "))";
+ else
+ break;
+ if (!isa<ObjCMethodDecl>(Caller)) {
+ IS << ' ';
+ SL = Caller->getBeginLoc();
}
- }
+ IS.flush();
+
+ DB << FixItHint::CreateInsertion(SL, Fixit);
+ } while (false);
S->Diag(Caller->getLocation(), diag::note_entity_declared_at) << Caller;
+
+ if (APK != Sema::FormatArgumentPassingKind::FAPK_Elsewhere) {
----------------
apple-fcloutier wrote:
We should only do this if `diag::warn_missing_format_attribute` is enabled
because it can cause new diagnostics to cascade, which users would have no way
to disable. You can check with
`!Diag.isIgnored(diag::warn_missing_format_attribute, Loc)`.
https://github.com/llvm/llvm-project/pull/166738
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits