[clang] bcefea8 - [clang][ASTImporter] Add import of thread safety attributes.
Balázs Kéri via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 5 03:54:01 PDT 2021
Author: Balázs Kéri
Date: 2021-10-05T13:08:31+02:00
New Revision: bcefea80a40ead1e1fbec2e6fa001dd4816ca5c2
URL: https://github.com/llvm/llvm-project/commit/bcefea80a40ead1e1fbec2e6fa001dd4816ca5c2
DIFF: https://github.com/llvm/llvm-project/commit/bcefea80a40ead1e1fbec2e6fa001dd4816ca5c2.diff
LOG: [clang][ASTImporter] Add import of thread safety attributes.
Attributes of "C/C++ Thread safety attributes" section in Attr.td
are added to ASTImporter. The not added attributes from this section
do not need special import handling.
Reviewed By: martong
Differential Revision: https://reviews.llvm.org/D110528
Added:
Modified:
clang/lib/AST/ASTImporter.cpp
clang/unittests/AST/ASTImporterTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index ece9e7fc01120..3c4f196a2db89 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -8634,6 +8634,174 @@ Expected<Attr *> ASTImporter::Import(const Attr *FromAttr) {
return ToAttrOrErr.takeError();
break;
}
+ case attr::AcquireCapability: {
+ const auto *From = cast<AcquireCapabilityAttr>(FromAttr);
+ AttrImporter AI(*this);
+ Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
+ From, AI.importArrayArg(From->args(), From->args_size()).value(),
+ From->args_size());
+ if (ToAttrOrErr)
+ ToAttr = *ToAttrOrErr;
+ else
+ return ToAttrOrErr.takeError();
+ break;
+ }
+ case attr::TryAcquireCapability: {
+ const auto *From = cast<TryAcquireCapabilityAttr>(FromAttr);
+ AttrImporter AI(*this);
+ Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
+ From, AI.importArg(From->getSuccessValue()).value(),
+ AI.importArrayArg(From->args(), From->args_size()).value(),
+ From->args_size());
+ if (ToAttrOrErr)
+ ToAttr = *ToAttrOrErr;
+ else
+ return ToAttrOrErr.takeError();
+ break;
+ }
+ case attr::ReleaseCapability: {
+ const auto *From = cast<ReleaseCapabilityAttr>(FromAttr);
+ AttrImporter AI(*this);
+ Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
+ From, AI.importArrayArg(From->args(), From->args_size()).value(),
+ From->args_size());
+ if (ToAttrOrErr)
+ ToAttr = *ToAttrOrErr;
+ else
+ return ToAttrOrErr.takeError();
+ break;
+ }
+ case attr::RequiresCapability: {
+ const auto *From = cast<RequiresCapabilityAttr>(FromAttr);
+ AttrImporter AI(*this);
+ Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
+ From, AI.importArrayArg(From->args(), From->args_size()).value(),
+ From->args_size());
+ if (ToAttrOrErr)
+ ToAttr = *ToAttrOrErr;
+ else
+ return ToAttrOrErr.takeError();
+ break;
+ }
+ case attr::GuardedBy: {
+ const auto *From = cast<GuardedByAttr>(FromAttr);
+ AttrImporter AI(*this);
+ Expected<Attr *> ToAttrOrErr =
+ AI.createImportedAttr(From, AI.importArg(From->getArg()).value());
+ if (ToAttrOrErr)
+ ToAttr = *ToAttrOrErr;
+ else
+ return ToAttrOrErr.takeError();
+ break;
+ }
+ case attr::PtGuardedBy: {
+ const auto *From = cast<PtGuardedByAttr>(FromAttr);
+ AttrImporter AI(*this);
+ Expected<Attr *> ToAttrOrErr =
+ AI.createImportedAttr(From, AI.importArg(From->getArg()).value());
+ if (ToAttrOrErr)
+ ToAttr = *ToAttrOrErr;
+ else
+ return ToAttrOrErr.takeError();
+ break;
+ }
+ case attr::AcquiredAfter: {
+ const auto *From = cast<AcquiredAfterAttr>(FromAttr);
+ AttrImporter AI(*this);
+ Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
+ From, AI.importArrayArg(From->args(), From->args_size()).value(),
+ From->args_size());
+ if (ToAttrOrErr)
+ ToAttr = *ToAttrOrErr;
+ else
+ return ToAttrOrErr.takeError();
+ break;
+ }
+ case attr::AcquiredBefore: {
+ const auto *From = cast<AcquiredBeforeAttr>(FromAttr);
+ AttrImporter AI(*this);
+ Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
+ From, AI.importArrayArg(From->args(), From->args_size()).value(),
+ From->args_size());
+ if (ToAttrOrErr)
+ ToAttr = *ToAttrOrErr;
+ else
+ return ToAttrOrErr.takeError();
+ break;
+ }
+ case attr::AssertExclusiveLock: {
+ const auto *From = cast<AssertExclusiveLockAttr>(FromAttr);
+ AttrImporter AI(*this);
+ Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
+ From, AI.importArrayArg(From->args(), From->args_size()).value(),
+ From->args_size());
+ if (ToAttrOrErr)
+ ToAttr = *ToAttrOrErr;
+ else
+ return ToAttrOrErr.takeError();
+ break;
+ }
+ case attr::AssertSharedLock: {
+ const auto *From = cast<AssertSharedLockAttr>(FromAttr);
+ AttrImporter AI(*this);
+ Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
+ From, AI.importArrayArg(From->args(), From->args_size()).value(),
+ From->args_size());
+ if (ToAttrOrErr)
+ ToAttr = *ToAttrOrErr;
+ else
+ return ToAttrOrErr.takeError();
+ break;
+ }
+ case attr::ExclusiveTrylockFunction: {
+ const auto *From = cast<ExclusiveTrylockFunctionAttr>(FromAttr);
+ AttrImporter AI(*this);
+ Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
+ From, AI.importArg(From->getSuccessValue()).value(),
+ AI.importArrayArg(From->args(), From->args_size()).value(),
+ From->args_size());
+ if (ToAttrOrErr)
+ ToAttr = *ToAttrOrErr;
+ else
+ return ToAttrOrErr.takeError();
+ break;
+ }
+ case attr::SharedTrylockFunction: {
+ const auto *From = cast<SharedTrylockFunctionAttr>(FromAttr);
+ AttrImporter AI(*this);
+ Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
+ From, AI.importArg(From->getSuccessValue()).value(),
+ AI.importArrayArg(From->args(), From->args_size()).value(),
+ From->args_size());
+ if (ToAttrOrErr)
+ ToAttr = *ToAttrOrErr;
+ else
+ return ToAttrOrErr.takeError();
+ break;
+ }
+ case attr::LockReturned: {
+ const auto *From = cast<LockReturnedAttr>(FromAttr);
+ AttrImporter AI(*this);
+ Expected<Attr *> ToAttrOrErr =
+ AI.createImportedAttr(From, AI.importArg(From->getArg()).value());
+ if (ToAttrOrErr)
+ ToAttr = *ToAttrOrErr;
+ else
+ return ToAttrOrErr.takeError();
+ break;
+ }
+ case attr::LocksExcluded: {
+ const auto *From = cast<LocksExcludedAttr>(FromAttr);
+ AttrImporter AI(*this);
+ Expected<Attr *> ToAttrOrErr = AI.createImportedAttr(
+ From, AI.importArrayArg(From->args(), From->args_size()).value(),
+ From->args_size());
+ if (ToAttrOrErr)
+ ToAttr = *ToAttrOrErr;
+ else
+ return ToAttrOrErr.takeError();
+ break;
+ }
default:
// FIXME: 'clone' copies every member but some of them should be imported.
diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp
index b7be56b36610d..3036b1c59d504 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -6564,6 +6564,31 @@ TEST_P(ASTImporterOptionSpecificTestBase, ImportFormatAttr) {
EXPECT_EQ(FromAttr->getType()->getName(), ToAttr->getType()->getName());
}
+TEST_P(ImportAttributes, ImportGuardedVar) {
+ GuardedVarAttr *FromAttr, *ToAttr;
+ importAttr<VarDecl>("int test __attribute__((guarded_var));", FromAttr,
+ ToAttr);
+}
+
+TEST_P(ImportAttributes, ImportPtGuardedVar) {
+ PtGuardedVarAttr *FromAttr, *ToAttr;
+ importAttr<VarDecl>("int *test __attribute__((pt_guarded_var));", FromAttr,
+ ToAttr);
+}
+
+TEST_P(ImportAttributes, ImportScopedLockable) {
+ ScopedLockableAttr *FromAttr, *ToAttr;
+ importAttr<CXXRecordDecl>("struct __attribute__((scoped_lockable)) test {};",
+ FromAttr, ToAttr);
+}
+
+TEST_P(ImportAttributes, ImportCapability) {
+ CapabilityAttr *FromAttr, *ToAttr;
+ importAttr<CXXRecordDecl>(
+ "struct __attribute__((capability(\"cap\"))) test {};", FromAttr, ToAttr);
+ EXPECT_EQ(FromAttr->getName(), ToAttr->getName());
+}
+
TEST_P(ImportAttributes, ImportAssertCapability) {
AssertCapabilityAttr *FromAttr, *ToAttr;
importAttr<FunctionDecl>(
@@ -6572,6 +6597,147 @@ TEST_P(ImportAttributes, ImportAssertCapability) {
checkImportVariadicArg(FromAttr->args(), ToAttr->args());
}
+TEST_P(ImportAttributes, ImportAcquireCapability) {
+ AcquireCapabilityAttr *FromAttr, *ToAttr;
+ importAttr<FunctionDecl>(
+ "void test(int A1, int A2) __attribute__((acquire_capability(A1, A2)));",
+ FromAttr, ToAttr);
+ checkImportVariadicArg(FromAttr->args(), ToAttr->args());
+}
+
+TEST_P(ImportAttributes, ImportTryAcquireCapability) {
+ TryAcquireCapabilityAttr *FromAttr, *ToAttr;
+ importAttr<FunctionDecl>(
+ "void test(int A1, int A2) __attribute__((try_acquire_capability(1, A1, "
+ "A2)));",
+ FromAttr, ToAttr);
+ checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue());
+ checkImportVariadicArg(FromAttr->args(), ToAttr->args());
+}
+
+TEST_P(ImportAttributes, ImportReleaseCapability) {
+ ReleaseCapabilityAttr *FromAttr, *ToAttr;
+ importAttr<FunctionDecl>(
+ "void test(int A1, int A2) __attribute__((release_capability(A1, A2)));",
+ FromAttr, ToAttr);
+ checkImportVariadicArg(FromAttr->args(), ToAttr->args());
+}
+
+TEST_P(ImportAttributes, ImportRequiresCapability) {
+ RequiresCapabilityAttr *FromAttr, *ToAttr;
+ importAttr<FunctionDecl>(
+ "void test(int A1, int A2) __attribute__((requires_capability(A1, A2)));",
+ FromAttr, ToAttr);
+ checkImportVariadicArg(FromAttr->args(), ToAttr->args());
+}
+
+TEST_P(ImportAttributes, ImportNoThreadSafetyAnalysis) {
+ NoThreadSafetyAnalysisAttr *FromAttr, *ToAttr;
+ importAttr<FunctionDecl>(
+ "void test() __attribute__((no_thread_safety_analysis));", FromAttr,
+ ToAttr);
+}
+
+TEST_P(ImportAttributes, ImportGuardedBy) {
+ GuardedByAttr *FromAttr, *ToAttr;
+ importAttr<VarDecl>(
+ R"(
+ int G;
+ int test __attribute__((guarded_by(G)));
+ )",
+ FromAttr, ToAttr);
+ checkImported(FromAttr->getArg(), ToAttr->getArg());
+}
+
+TEST_P(ImportAttributes, ImportPtGuardedBy) {
+ PtGuardedByAttr *FromAttr, *ToAttr;
+ importAttr<VarDecl>(
+ R"(
+ int G;
+ int *test __attribute__((pt_guarded_by(G)));
+ )",
+ FromAttr, ToAttr);
+ checkImported(FromAttr->getArg(), ToAttr->getArg());
+}
+
+TEST_P(ImportAttributes, ImportAcquiredAfter) {
+ AcquiredAfterAttr *FromAttr, *ToAttr;
+ importAttr<VarDecl>(
+ R"(
+ struct __attribute__((lockable)) L {};
+ L A1;
+ L A2;
+ L test __attribute__((acquired_after(A1, A2)));
+ )",
+ FromAttr, ToAttr);
+ checkImportVariadicArg(FromAttr->args(), ToAttr->args());
+}
+
+TEST_P(ImportAttributes, ImportAcquiredBefore) {
+ AcquiredBeforeAttr *FromAttr, *ToAttr;
+ importAttr<VarDecl>(
+ R"(
+ struct __attribute__((lockable)) L {};
+ L A1;
+ L A2;
+ L test __attribute__((acquired_before(A1, A2)));
+ )",
+ FromAttr, ToAttr);
+ checkImportVariadicArg(FromAttr->args(), ToAttr->args());
+}
+
+TEST_P(ImportAttributes, ImportAssertExclusiveLock) {
+ AssertExclusiveLockAttr *FromAttr, *ToAttr;
+ importAttr<FunctionDecl>("void test(int A1, int A2) "
+ "__attribute__((assert_exclusive_lock(A1, A2)));",
+ FromAttr, ToAttr);
+ checkImportVariadicArg(FromAttr->args(), ToAttr->args());
+}
+
+TEST_P(ImportAttributes, ImportAssertSharedLock) {
+ AssertSharedLockAttr *FromAttr, *ToAttr;
+ importAttr<FunctionDecl>(
+ "void test(int A1, int A2) __attribute__((assert_shared_lock(A1, A2)));",
+ FromAttr, ToAttr);
+ checkImportVariadicArg(FromAttr->args(), ToAttr->args());
+}
+
+TEST_P(ImportAttributes, ImportExclusiveTrylockFunction) {
+ ExclusiveTrylockFunctionAttr *FromAttr, *ToAttr;
+ importAttr<FunctionDecl>(
+ "void test(int A1, int A2) __attribute__((exclusive_trylock_function(1, "
+ "A1, A2)));",
+ FromAttr, ToAttr);
+ checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue());
+ checkImportVariadicArg(FromAttr->args(), ToAttr->args());
+}
+
+TEST_P(ImportAttributes, ImportSharedTrylockFunction) {
+ SharedTrylockFunctionAttr *FromAttr, *ToAttr;
+ importAttr<FunctionDecl>(
+ "void test(int A1, int A2) __attribute__((shared_trylock_function(1, A1, "
+ "A2)));",
+ FromAttr, ToAttr);
+ checkImported(FromAttr->getSuccessValue(), ToAttr->getSuccessValue());
+ checkImportVariadicArg(FromAttr->args(), ToAttr->args());
+}
+
+TEST_P(ImportAttributes, ImportLockReturned) {
+ LockReturnedAttr *FromAttr, *ToAttr;
+ importAttr<FunctionDecl>(
+ "void test(int A1) __attribute__((lock_returned(A1)));", FromAttr,
+ ToAttr);
+ checkImported(FromAttr->getArg(), ToAttr->getArg());
+}
+
+TEST_P(ImportAttributes, ImportLocksExcluded) {
+ LocksExcludedAttr *FromAttr, *ToAttr;
+ importAttr<FunctionDecl>(
+ "void test(int A1, int A2) __attribute__((locks_excluded(A1, A2)));",
+ FromAttr, ToAttr);
+ checkImportVariadicArg(FromAttr->args(), ToAttr->args());
+}
+
template <typename T>
auto ExtendWithOptions(const T &Values, const std::vector<std::string> &Args) {
auto Copy = Values;
More information about the cfe-commits
mailing list