[clang-tools-extra] [clang-tidy] Add check to diagnose coroutine-hostile RAII objects (PR #68738)

Piotr Zegar via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 11 06:45:54 PDT 2023


================
@@ -0,0 +1,82 @@
+//===--- CoroutineSuspensionHostileCheck.cpp - clang-tidy --------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "CoroutineHostileRAIICheck.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/AST/Attrs.inc"
+#include "clang/AST/Decl.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/Type.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::misc {
+CoroutineHostileRAIICheck::CoroutineHostileRAIICheck(StringRef Name,
+                                                     ClangTidyContext *Context)
+    : ClangTidyCheck(Name, Context) {
+  for (StringRef Denied :
+       utils::options::parseStringList(Options.get("RAIIDenyList", ""))) {
+    Denied.consume_front("::");
+    RAIIDenyList.push_back(Denied);
+  }
+}
+
+void CoroutineHostileRAIICheck::registerMatchers(MatchFinder *Finder) {
+  // A suspension happens with co_await or co_yield.
+  Finder->addMatcher(coawaitExpr().bind("suspension"), this);
+  Finder->addMatcher(coyieldExpr().bind("suspension"), this);
+}
+
+void CoroutineHostileRAIICheck::checkVarDecl(VarDecl *VD) {
+  RecordDecl *RD = VD->getType().getCanonicalType()->getAsRecordDecl();
+  if (RD->hasAttr<clang::ScopedLockableAttr>()) {
+    diag(VD->getLocation(),
+         "%0 holds a lock across a suspension point of coroutine and could be "
+         "unlocked by a different thread")
+        << VD;
+  }
+  if (std::find(RAIIDenyList.begin(), RAIIDenyList.end(),
+                RD->getQualifiedNameAsString()) != RAIIDenyList.end()) {
----------------
PiotrZSL wrote:

would be nice to somehow utilize MatchesAnyListedNameMatcher, this could be possible if this would be rewritten into AST matcher or just extracting NameMatcher from it (make it public) and use here.

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


More information about the cfe-commits mailing list