[PATCH] D67778: [Consumed] Narrow Subject for some attributes

Nicholas Allegra via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 19 16:54:12 PDT 2019


comex created this revision.
comex added a reviewer: dblaikie.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This is the former second part of https://reviews.llvm.org/D67740 that was split out (and rewritten).

Error out when the `callable_when`, `set_typestate` and `test_typestate` attributes are applied to a constructor or static method; previously Clang would ignore them or crash, depending on the attribute.


Repository:
  rC Clang

https://reviews.llvm.org/D67778

Files:
  include/clang/Basic/Attr.td
  test/SemaCXX/warn-consumed-parsing.cpp


Index: test/SemaCXX/warn-consumed-parsing.cpp
===================================================================
--- test/SemaCXX/warn-consumed-parsing.cpp
+++ test/SemaCXX/warn-consumed-parsing.cpp
@@ -12,7 +12,7 @@
   void callableWhen()   __attribute__ ((callable_when())); // expected-error {{'callable_when' attribute takes at least 1 argument}}
 };
 
-int var0 SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to functions}}
+int var0 SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to non-static non-constructor member functions}}
 int var1 TEST_TYPESTATE(consumed); // expected-warning {{'test_typestate' attribute only applies to}}
 int var2 CALLABLE_WHEN("consumed"); // expected-warning {{'callable_when' attribute only applies to}}
 int var3 CONSUMABLE(consumed); // expected-warning {{'consumable' attribute only applies to classes}}
@@ -58,7 +58,11 @@
 }
 
 struct CONSUMABLE(unknown) UselessAttrs {
+  static void x() SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to non-static non-constructor member functions}}
+  UselessAttrs() SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to non-static non-constructor member functions}}
+  UselessAttrs(int) CALLABLE_WHEN(consumed); // expected-warning {{'callable_when' attribute only applies to non-static non-constructor member functions}}
   void operator+(UselessAttrs) SET_TYPESTATE(consumed); // OK
+  static void *operator new(unsigned long) SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to non-static non-constructor member functions}}
   template <typename T>
   void a([[clang::param_typestate(consumed)]] const int &) {} // expected-warning {{attribute 'param_typestate' invalid for parameter of type 'const int &': expected a consumable class type as a value, reference, or rvalue reference}}
   void b([[clang::return_typestate(consumed)]] UselessAttrs *) {} // expected-warning {{attribute 'return_typestate' invalid for parameter of type 'UselessAttrs *': expected a consumable class type as a value, reference, or rvalue reference}}
@@ -71,7 +75,7 @@
     c(42);
   }
 };
-void operator-(UselessAttrs, UselessAttrs) SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to functions}}
+void operator-(UselessAttrs, UselessAttrs) SET_TYPESTATE(consumed); // expected-warning {{'set_typestate' attribute only applies to non-static non-constructor member functions}}
 
 template <typename T, typename U>
 struct CONSUMABLE(unknown) ClassTemplateSpecialization;
Index: include/clang/Basic/Attr.td
===================================================================
--- include/clang/Basic/Attr.td
+++ include/clang/Basic/Attr.td
@@ -96,6 +96,11 @@
                                        [{!S->isStatic()}],
                                        "non-static member functions">;
 
+def NonStaticNonConstructorCXXMethod
+    : SubsetSubject<CXXMethod,
+                    [{!S->isStatic() && !isa<CXXConstructorDecl>(S)}],
+                    "non-static non-constructor member functions">;
+
 def NonStaticNonConstCXXMethod
     : SubsetSubject<CXXMethod,
                     [{!S->isStatic() && !S->isConst()}],
@@ -2725,7 +2730,7 @@
   // to C++ function (but doesn't require it to be a member function).
   // FIXME: should this attribute have a CPlusPlus language option?
   let Spellings = [Clang<"callable_when", 0>];
-  let Subjects = SubjectList<[CXXMethod]>;
+  let Subjects = SubjectList<[NonStaticNonConstructorCXXMethod]>;
   let Args = [VariadicEnumArgument<"CallableStates", "ConsumedState",
                                    ["unknown", "consumed", "unconsumed"],
                                    ["Unknown", "Consumed", "Unconsumed"]>];
@@ -2761,7 +2766,7 @@
   // to C++ function (but doesn't require it to be a member function).
   // FIXME: should this attribute have a CPlusPlus language option?
   let Spellings = [Clang<"set_typestate", 0>];
-  let Subjects = SubjectList<[CXXMethod]>;
+  let Subjects = SubjectList<[NonStaticNonConstructorCXXMethod]>;
   let Args = [EnumArgument<"NewState", "ConsumedState",
                            ["unknown", "consumed", "unconsumed"],
                            ["Unknown", "Consumed", "Unconsumed"]>];
@@ -2773,7 +2778,7 @@
   // to C++ function (but doesn't require it to be a member function).
   // FIXME: should this attribute have a CPlusPlus language option?
   let Spellings = [Clang<"test_typestate", 0>];
-  let Subjects = SubjectList<[CXXMethod]>;
+  let Subjects = SubjectList<[NonStaticNonConstructorCXXMethod]>;
   let Args = [EnumArgument<"TestState", "ConsumedState",
                            ["consumed", "unconsumed"],
                            ["Consumed", "Unconsumed"]>];


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D67778.220922.patch
Type: text/x-patch
Size: 4867 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190919/26e1b46a/attachment.bin>


More information about the cfe-commits mailing list