================ @@ -6849,6 +6849,71 @@ static void handleSwiftAsyncAttr(Sema &S, Decl *D, const ParsedAttr &AL) { checkSwiftAsyncErrorBlock(S, D, ErrorAttr, AsyncAttr); } +// Warn if parent function misses format attribute. Parent function misses +// format attribute if there is an argument format string forwarded to calling +// function with format attribute, parent function has a parameter which is +// either char or string or pointer to char and parent function format attribute +// type does not match with calling function format attribute type. +void Sema::DiagnoseMissingFormatAttributes(const FunctionDecl *FDecl, + ArrayRef<const Expr *> Args, + SourceLocation Loc) { + assert(FDecl); + + // Check if function has format attribute with forwarded format string. + IdentifierInfo *AttrType; + if (!llvm::any_of( + FDecl->specific_attrs<FormatAttr>(), [&](const FormatAttr *Attr) { + if (!Args[Attr->getFirstArg()]->getReferencedDeclOfCallee()) + return false; + + AttrType = Attr->getType(); + return true; + })) + return; + + const FunctionDecl *ParentFuncDecl = getCurFunctionDecl(); + if (!ParentFuncDecl) + return; + + // Check if parent function has char, string or pointer to char parameter. + unsigned int StringIndex = 0; + if (!llvm::any_of( + ParentFuncDecl->parameters(), [&](const ParmVarDecl *Param) { + StringIndex = Param->getFunctionScopeIndex() + 1; + QualType Ty = Param->getType(); + if (isNSStringType(Ty, Context, true)) + return true; + if (isCFStringType(Ty, Context)) + return true; + if (Ty->isPointerType() && + Ty->castAs<PointerType>()->getPointeeType()->isCharType()) + return true; + return false; + })) + return; + + // Check if there is parent function format attribute which type matches + // calling function format attribute type. + if (llvm::any_of( + ParentFuncDecl->specific_attrs<FormatAttr>(), + [&](const FormatAttr *Attr) { return Attr->getType() == AttrType; })) + return; + + unsigned int FirstToCheck = + ParentFuncDecl->isVariadic() ? (ParentFuncDecl->getNumParams() + 1) : 0; + + // Diagnose missing format attributes + std::string InsertionText; + llvm::raw_string_ostream OS(InsertionText); + OS << "__attribute__((format(" + AttrType->getName() + ", " + + std::to_string(StringIndex) + ", " + std::to_string(FirstToCheck) + + ")))"; ---------------- AaronBallman wrote:
```suggestion OS << "__attribute__((format(" + AttrType->getName() << ", " << std::to_string(StringIndex) << ", " << std::to_string(FirstToCheck) << ")))"; ``` Might as well just stream all the strings in rather than allocate a string and stream that in. https://github.com/llvm/llvm-project/pull/70024 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits