[clang] [clang] Catch missing format attributes (PR #70024)

Budimir Aranđelović via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 18 08:39:48 PDT 2024


================
@@ -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())
----------------
budimirarandjelovicsyrmia wrote:

By analyzing LLVM code, I found that calls inside template body are built differently than calls inside non-template body. It is obvious for template-dependent calls, as these calls are not built as resolved expression calls. Regarding template-independent calls, they can be processed as resolved expression calls, but function checkCall(), where is diagnosing, does not make checks for these calls. At the beggining of checkCall() there are FIX-ME comment which says that template calls should be checked in template definition.
It would be significant for me if you know if there is a part of code that process content of template body and definition. Otherwise, I think it is okay to postpone addressing this comment.

https://github.com/llvm/llvm-project/pull/70024


More information about the cfe-commits mailing list