[clang] [clang] Warn on mismatched RequiresCapability attributes (PR #67520)

Aaron Puchert via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 21 14:08:12 PST 2024


================
@@ -2263,6 +2265,27 @@ static bool neverReturns(const CFGBlock *B) {
   return false;
 }
 
+void ThreadSafetyAnalyzer::checkMismatchedFunctionAttrs(const NamedDecl *ND) {
+  auto collectCapabilities = [&](const Decl *D) {
+    CapExprSet Caps;
+    for (const auto *A : D->specific_attrs<RequiresCapabilityAttr>()) {
+      for (const Expr *E : A->args())
+        Caps.push_back_nodup(SxBuilder.translateAttrExpr(E, nullptr));
+    }
+    return Caps;
+  };
+
+  auto NDArgs = collectCapabilities(ND);
+  for (const Decl *D = ND->getPreviousDecl(); D; D = D->getPreviousDecl()) {
+    auto DArgs = collectCapabilities(D);
+
+    for (const auto &[A, B] : zip_longest(NDArgs, DArgs)) {
+      if (!A || !B || !A->equals(*B))
+        Handler.handleAttributeMismatch(ND, cast<NamedDecl>(D));
+    }
----------------
aaronpuchert wrote:

Since we inherit the attributes and deduplicate capabilities here via `push_back_nodup`, this seems to be equivalent to just comparing sizes. We would only have to go through the vectors if we actually wanted to find the missing attribute.

Equivalently, we could also collect the capabilities from attributes on the first declaration, and then on subsequent declarations check _non-inherited_ attributes against the capability set of the first declaration. That would also make it easy to point out which capability is missing on the first declaration. So we can print a better diagnostic.

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


More information about the cfe-commits mailing list