@@ -2265,27 +2265,37 @@ static bool neverReturns(const CFGBlock *B) {
2265
2265
return false ;
2266
2266
}
2267
2267
2268
- void ThreadSafetyAnalyzer::checkMismatchedFunctionAttrs (const NamedDecl *ND) {
2269
- auto collectCapabilities = [&](const Decl *D) {
2270
- CapExprSet Caps;
2271
- for (const auto *A : D->specific_attrs <RequiresCapabilityAttr>()) {
2272
- for (const Expr *E : A->args ())
2273
- Caps.push_back_nodup (SxBuilder.translateAttrExpr (E, nullptr ));
2274
- }
2275
- return Caps;
2276
- };
2268
+ template <typename AttrT>
2269
+ static CapExprSet collectAttrArgs (SExprBuilder &SxBuilder, const Decl *D) {
2270
+ CapExprSet Caps;
2271
+ for (const auto *A : D->specific_attrs <AttrT>()) {
2272
+ for (const Expr *E : A->args ())
2273
+ Caps.push_back_nodup (SxBuilder.translateAttrExpr (E, nullptr ));
2274
+ }
2275
+ return Caps;
2276
+ }
2277
+
2278
+ template <typename AttrT>
2279
+ static void maybeDiagnoseFunctionAttrs (const NamedDecl *ND,
2280
+ SExprBuilder &SxBuilder,
2281
+ ThreadSafetyHandler &Handler) {
2277
2282
2278
- CapExprSet NDArgs = collectCapabilities (ND);
2283
+ // FIXME: The diagnostic here is suboptimal. It would be better to print
2284
+ // what attributes are missing in the first declaration.
2285
+ CapExprSet NDArgs = collectAttrArgs<AttrT>(SxBuilder, ND);
2279
2286
for (const Decl *D = ND->getPreviousDecl (); D; D = D->getPreviousDecl ()) {
2280
- CapExprSet DArgs = collectCapabilities ( D);
2287
+ CapExprSet DArgs = collectAttrArgs<AttrT>(SxBuilder, D);
2281
2288
2282
- for (const auto &[A, B] : zip_longest (NDArgs, DArgs)) {
2283
- if (!A || !B || !A->equals (*B))
2284
- Handler.handleAttributeMismatch (ND, cast<NamedDecl>(D));
2285
- }
2289
+ if (NDArgs.size () != DArgs.size ())
2290
+ Handler.handleAttributeMismatch (ND, cast<NamedDecl>(D));
2286
2291
}
2287
2292
}
2288
2293
2294
+ void ThreadSafetyAnalyzer::checkMismatchedFunctionAttrs (const NamedDecl *ND) {
2295
+ maybeDiagnoseFunctionAttrs<RequiresCapabilityAttr>(ND, SxBuilder, Handler);
2296
+ maybeDiagnoseFunctionAttrs<ReleaseCapabilityAttr>(ND, SxBuilder, Handler);
2297
+ }
2298
+
2289
2299
// / Check a function's CFG for thread-safety violations.
2290
2300
// /
2291
2301
// / We traverse the blocks in the CFG, compute the set of mutexes that are held
0 commit comments