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 + : SubsetSubjectisStatic() && !isa(S)}], + "non-static non-constructor member functions">; + def NonStaticNonConstCXXMethod : SubsetSubjectisStatic() && !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"]>]; 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 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 struct CONSUMABLE(unknown) ClassTemplateSpecialization;