This is an archive of the discontinued LLVM Phabricator instance.

[attributes] Add a family of OS_CONSUMED, OS_RETURNS and OS_RETURNS_RETAINED attributes
ClosedPublic

Authored by george.karpenkov on Nov 26 2018, 12:14 PM.

Details

Summary

The addition adds three attributes for communicating ownership,
analogous to existing NS_ and CF_ attributes.
The attributes are meant to be used for communicating ownership of all objects in XNU (Darwin kernel) and all of the kernel modules.
The ownership model there is very similar, but still different from the Foundation model, so we think that introducing a new family of attributes is appropriate.

The addition required a sizeable refactoring of the existing code for CF_ and NS_ ownership attributes,
due to tight coupling and the fact that differentiating between the types was previously done using a boolean.

Diff Detail

Event Timeline

aaron.ballman added inline comments.Nov 27 2018, 1:42 PM
clang/include/clang/Basic/Attr.td
853

No new undocumented attributes, please. (Same for the other attributes.)

856

Are there no subjects for this attribute?

861

Or this one?

clang/lib/Sema/SemaDeclAttr.cpp
395–400

Did clang-format do this?

415

T &&ExtraArg and std::forward it below?

416

Missing && here, no?

428

I don't see a strong relationship between this function name and the fact that the check function is doing something with type checking. The function sounds more generic than it really is.

432

I don't like this being a cast<> here. I would do: if (auto *VD = dyn_cast<ValueDecl>(D)) { ... } to avoid the assertion.

434

Is this top-level const because you planned to assign to a const reference, or do you really want the copy here? If you want the copy, please drop the const.

4843

Spurious newline.

clang/test/SemaTemplate/attributes.cpp
57–76 ↗(On Diff #175311)

These should be in a test in Sema, not SemaTemplate (they're not related to template instantiation).

george.karpenkov marked 18 inline comments as done.
george.karpenkov added inline comments.
clang/include/clang/Basic/Attr.td
853

OK

856

I've copied it from the other family of attributes; TBH I'm not sure what the field is doing. I'll see whether I can come up with a good value.

861

OK, same as above --- I'll try to put something reasonable there.

clang/lib/Sema/SemaDeclAttr.cpp
395–400

It's a different function from the previous one -- I have introduced another handleSimpleAttribute which takes a SourceRange and a SpellingIndex directly, and now the previous one calls it.

415

OK

428

Ideally it should really take a check on a Decl, and not a type,
but in this case it led to unnecessary code duplication (as in one of the use cases only type, and not the decl is available).
I think it's quite generic - it performs and check on the declaration type.

In such situations I usually favor the YAGNI principle - leave it like this, and if someone needs a check on a decl, and not an attribute, this function could easily be generalized.

432

OK. In that case being not a value decl would implicitly fial the diagnostic check.

434

I dislike having references to returned values, as RVO would avoid the copy anyway.

Conceptually, it should be a reference, but in this case we don't need it (due to RVO),
and having an extra copy before any diagnostic is emitted won't hurt.

Later on it is passed as a parameter to a function accepting a const reference.

4843

I like to follow Google style guide with a newline preceding each comment, but OK.

clang/test/SemaTemplate/attributes.cpp
57–76 ↗(On Diff #175311)

OK

aaron.ballman added inline comments.Nov 27 2018, 4:24 PM
clang/include/clang/Basic/Attr.td
856

The subject list specifies what kind of entities the attribute can appertain to; it takes care of some of the automated testing for attributes so you don't have to do the work manually.

1634

Should this also point to RetainBehaviorDocs now?

clang/include/clang/Basic/AttrDocs.td
860

You can re-flow the documentation for 80-col.

882–883

These are probably meant to be os_* and not cf_*.

clang/lib/Sema/SemaDeclAttr.cpp
395–400

My comment was more about the formatting. I saw that this is a new overload, but the old formatting was very strange. It looks correct now.

428

I think it's quite generic - it performs and check on the declaration type.

Not all declarations have types. For instance, you can apply an attribute to a namespace declaration (such as [[deprecated]]). So my concern is more that this function isn't actually generic when it sounds like it is.

In such situations I usually favor the YAGNI principle - leave it like this, and if someone needs a check on a decl, and not an attribute, this function could easily be generalized.

Yeah, I don't think we need to change the behavior of the function, but I am wondering if it makes sense to rename it to handleSimpleAttributeWithTypeCheck() or some-such to make it more clear that the attribute must appertain to a declaration with a type. Alternatively, instead of taking a Decl *, it could accept a ValueDecl * instead and force the user to only pass in declarations with types to the call.

434

I'm reluctantly okay with using value semantics here (I have a preference for using const reference semantics instead so we can avoid a needless local copy), but the top-level const should go in that case (we don't typically use that idiom in the project). I was only asking because I could not tell if that was a typo for const Sema::SemaDiagnosticBuilder & or not.

clang/test/Sema/attr-osobject.cpp
2

This doesn't need to pass -std=c++11.

5

Can you run this file through clang-format?

23

You should also add tests that ensure that the attribute does not accept arguments and doesn't appertain to things that are not functions.

Related Q: should all of these attributes also appertain to function pointers? (This may be orthogonal to this patch.)

george.karpenkov marked 10 inline comments as done.
george.karpenkov added inline comments.
clang/lib/Sema/SemaDeclAttr.cpp
428

OK, let's accept a ValueDecl.

434

Dropping const.
I don't think we should have a reference here, as then there is no clear owner for the builder, and it becomes easy to end up with a dead reference.

clang/test/Sema/attr-osobject.cpp
23

Attributes should only apply to pointers to objects (inside the analyzer it's even more restricted: only pointers to objects inheriting from OSObject).

aaron.ballman added inline comments.Nov 28 2018, 4:47 AM
clang/include/clang/Basic/Attr.td
839

The CFReturnsRetained (and NotRetained) use a commented-out subject list that includes ObjCProperty. Do the OS functions also apply to ObjCProperty objects? I believe I added the above commented out because we couldn't automate something about it, and I vaguely recall the subject list was my best effort at gleaning the subjects (so it might be inaccurate).

clang/lib/Sema/SemaDeclAttr.cpp
4772–4786

This doesn't look formatted properly to me. Did clang-format do this?

4786–4787

Can remove spurious newline.

clang/test/Sema/attr-osobject.cpp
23

Do the same kind of tests for os_returns_retained and os_returns_not_retained.

You should also add an Objective-C test for their methods and properties (those tests can be positive tests showing that no diagnostics are expected).

george.karpenkov marked 5 inline comments as done.
george.karpenkov added inline comments.
clang/include/clang/Basic/Attr.td
839

No, they shouldn't apply to properties.

aaron.ballman added inline comments.Nov 28 2018, 11:05 AM
clang/include/clang/Basic/Attr.td
839

handleXReturnsXRetainedAttr() suggests otherwise for the other attributes, so is there a reason this one is different?

For instance: https://godbolt.org/z/stN5rO

clang/lib/Sema/SemaDeclAttr.cpp
4838

This seems to imply that an ObjCPropertyDecl is acceptable to all of the returns_*_retained attributes (was there before your refactoring).

4862

And then this suggests that NS and OS do not accept properties (similar below for CF).

If NS and CF are expected to work on properties, we should probably update this diagnostic (doesn't have to be part of this patch). If they aren't supposed to work on properties, then we should fix the logic.

george.karpenkov marked 2 inline comments as done.
george.karpenkov added inline comments.
clang/include/clang/Basic/Attr.td
839

Hm, that's an interesting point, thanks for bringing this up.

On one hand, adding OS_RETURNS_RETAINED to properties makes no sense - the semantics of the program is really weird if accessing the property transfers the ownership.
But on the other hand it's explicitly allowed and tested in attr-cf_returns on CF_* properties, so we should probably allow it as well.

clang/lib/Sema/SemaDeclAttr.cpp
4862

They do work, and it's actually explicitly tested. I think for the purpose of symmetry we should also support it for OS_* attributes then.

Since a lot of code relies on behavior of NS_* properties for code generation, I'm not going to change the logic for that behavior, unless the actual need arises.
FWIW the error message is actually correct when the attribute is added to the property of the unexpected type.

aaron.ballman accepted this revision.Nov 29 2018, 5:38 AM

LGTM aside from a small documentation nit.

clang/include/clang/Basic/AttrDocs.td
853

You should add a quick note somewhere in here that some of these attributes appertains to functions, Objective-C methods, and Objective-C properties.

clang/lib/Sema/SemaDeclAttr.cpp
4862

FWIW the error message is actually correct when the attribute is added to the property of the unexpected type.

I think it's incorrect -- that error message results in this, which doesn't mention ObjC properties: https://godbolt.org/z/UZHHN_

I can fix this up in a separate patch, however.

This revision is now accepted and ready to land.Nov 29 2018, 5:38 AM
This revision was automatically updated to reflect the committed changes.
aaron.ballman added inline comments.Nov 30 2018, 6:20 AM
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
4862 ↗(On Diff #176018)

I mentioned that I could fix this up in another patch, but there's a different subtlety here -- you can apply NSReturnsRetained and friends to types. See test\SemaObjC\attr-ns_returns_retained.m for an example -- where it's being added to a block type. It also seems to appertain to block literals (test\SemaObjC\block-literal-with-attribute.m).

Should the OS versions also apply to types and block literals?

george.karpenkov marked an inline comment as done.Nov 30 2018, 11:23 AM
george.karpenkov added inline comments.
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
4862 ↗(On Diff #176018)

OS versions should not apply to block literals, neither they should be applicable to block types.

aaron.ballman added inline comments.Nov 30 2018, 11:24 AM
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
4862 ↗(On Diff #176018)

Can you add some tests to ensure it's properly diagnosed?

george.karpenkov marked an inline comment as done.Nov 30 2018, 5:40 PM
george.karpenkov added inline comments.
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
4862 ↗(On Diff #176018)

@aaron.ballman Do you mean something like this?

diff --git a/clang/test/Sema/attr-osobject.mm b/clang/test/Sema/attr-osobject.mm
index dbd9122a8fa..ffb4394e4bc 100644
--- a/clang/test/Sema/attr-osobject.mm
+++ b/clang/test/Sema/attr-osobject.mm
@@ -1,6 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
-
-// expected-no-diagnostics
+// RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s

 struct S {};

@@ -9,3 +7,5 @@ @interface I
   - (S*) generateS __attribute__((os_returns_retained));
   - (void) takeS:(S*) __attribute__((os_consumed)) s;
 @end
+
+typedef __attribute__((os_returns_retained)) id (^blockType)(); // expected-warning{{'os_returns_retained' attribute only applies to functions, Objective-C methods, and Objective-C properties}}
aaron.ballman added inline comments.Dec 1 2018, 9:46 AM
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
4862 ↗(On Diff #176018)

Yup! Also:

__auto_type b = ^ id (id filter)  __attribute__((os_returns_retained))  {
  return filter;
};

This is accepted by ns_returns_retained, so it would be good to clearly show it's not supported by os_returns_retained.

george.karpenkov marked an inline comment as done.Dec 5 2018, 5:25 PM
george.karpenkov added inline comments.
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
4862 ↗(On Diff #176018)