]> granicus.if.org Git - clang/commitdiff
Capabilities are required to pass a name specifying what type of capability is being...
authorAaron Ballman <aaron@aaronballman.com>
Wed, 5 Mar 2014 21:47:13 +0000 (21:47 +0000)
committerAaron Ballman <aaron@aaronballman.com>
Wed, 5 Mar 2014 21:47:13 +0000 (21:47 +0000)
Note that for backwards compatibility, an unnamed capability will default to being a "mutex." This allows the deprecated lockable attribute to continue to function.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@203012 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/Attr.td
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDeclAttr.cpp
test/Sema/attr-capabilities.c

index b04aa46191cec9f9511b3ee27b289c1c65ecb665..aae669db2f2225d593048698f0bd694506be2a13 100644 (file)
@@ -1306,6 +1306,10 @@ def Capability : InheritableAttr {
                     [GNU<"shared_capability">,
                      CXX11<"clang","shared_capability">]>];
   let Documentation = [Undocumented];
+  let AdditionalMembers = [{
+    bool isMutex() const { return getName().equals_lower("mutex"); }
+    bool isRole() const { return getName().equals_lower("role"); }
+  }];
 }
 
 def AssertCapability : InheritableAttr {
index 15c7a53a9b43975b1e5f5c159096fa5ebc50b7a8..c23b5e25c4e9baccba52c80db9760d73180832a1 100644 (file)
@@ -2153,6 +2153,9 @@ def note_overridden_method : Note<
   "overridden method is here">;
 
 // Thread Safety Attributes
+def warn_invalid_capability_name : Warning<
+  "invalid capability name '%0'; capability name must be 'mutex' or 'role'">,
+  InGroup<ThreadSafetyAttributes>, DefaultIgnore;
 def warn_thread_attribute_ignored : Warning<
   "ignoring %0 attribute because its argument is invalid">,
   InGroup<ThreadSafetyAttributes>, DefaultIgnore;
index 2600a4fcb0b92839cf3e9bc01e82df51b568ff11..739aee92a1e22d1e0d84b6430721c78a1f17b336 100644 (file)
@@ -3892,12 +3892,20 @@ static void handleCapabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   // parameters. However, semantically, both attributes represent the same
   // concept, and so they use the same semantic attribute. Eventually, the
   // lockable attribute will be removed.
-  StringRef N;
+  //
+  // For backwards compatibility, any capability which has no specified string
+  // literal will be considered a "mutex."
+  StringRef N("mutex");
   SourceLocation LiteralLoc;
   if (Attr.getKind() == AttributeList::AT_Capability &&
       !S.checkStringLiteralArgumentAttr(Attr, 0, N, &LiteralLoc))
     return;
 
+  // Currently, there are only two names allowed for a capability: role and
+  // mutex (case insensitive). Diagnose other capability names.
+  if (!N.equals_lower("mutex") && !N.equals_lower("role"))
+    S.Diag(LiteralLoc, diag::warn_invalid_capability_name) << N;
+
   D->addAttr(::new (S.Context) CapabilityAttr(Attr.getRange(), S.Context, N,
                                         Attr.getAttributeSpellingListIndex()));
 }
index 7a83403934fd9a2e06c98f00ab9685dc8c348add..6ce84dceabf4cbf37f6d9b4ee1adba3384a129ab 100644 (file)
@@ -1,9 +1,12 @@
 // RUN: %clang_cc1 -fsyntax-only -Wthread-safety -verify %s\r
 \r
-struct __attribute__((capability("thread role"))) ThreadRole {};\r
+struct __attribute__((capability("role"))) ThreadRole {};\r
 struct __attribute__((shared_capability("mutex"))) Mutex {};\r
 struct NotACapability {};\r
 \r
+// Test an invalid capability name\r
+struct __attribute__((capability("wrong"))) IncorrectName {}; // expected-warning {{invalid capability name 'wrong'; capability name must be 'mutex' or 'role'}}\r
+\r
 int Test1 __attribute__((capability("test1")));  // expected-error {{'capability' attribute only applies to structs}}\r
 int Test2 __attribute__((shared_capability("test2"))); // expected-error {{'shared_capability' attribute only applies to structs}}\r
 int Test3 __attribute__((acquire_capability("test3")));  // expected-error {{'acquire_capability' attribute only applies to functions}}\r