This is an archive of the discontinued LLVM Phabricator instance.

Fix mangled name of method with ns_consumed parameters.
ClosedPublic

Authored by sdefresne on May 10 2016, 9:45 AM.

Details

Reviewers
rjmccall
thakis
Summary

When a function/method use a parameter with "ns_consumed" attribute,
ensure that the mangled name is the same whether -fobjc-arc is used
or not.

Since "ns_consumed" attribute is generally used to inform ARC that
a function/method does sink the reference, it mean it is usually
implemented in a compilation unit compiled without -fobjc-arc but
used form a compilation unit compiled with it.

Originally found while trying to use "ns_consumed" attribute in an
Objective-C++ file in Chromium (http://crbug.com/599980) where it
caused a linker error.

Regression introduced by revision 262278 (previously the attribute
was incorrectly not part of the mangled name).

Diff Detail

Event Timeline

sdefresne updated this revision to Diff 56735.May 10 2016, 9:45 AM
sdefresne retitled this revision from to Fix mangled name of method with ns_consumed parameters..
sdefresne updated this object.
sdefresne added a reviewer: rjmccall.
sdefresne added a subscriber: cfe-commits.
rjmccall edited edge metadata.May 10 2016, 10:15 AM

This is a good catch, thanks!

As a slight adjustment, It's probably better to just ignore this attribute when mangling the function type of an entity, the same way that we generally don't mangle return types because they don't affect overloading. That will require an extra flag to be passed down in a few places, but that's pretty reasonable. This will generally allow NS_CONSUMED and NS_RETURNS_RETAINED to be placed on existing APIs without changing their mangling unless the attribute is used in a secondary position (such as the type of an argument).

Finally, you should give ns_returns_retained the same treatment, as well as the parameter-ABI attributes.

This is a good catch, thanks!

Thank you for the quick reply.

Please excuse me if I misunderstood you or if my remark appear off the mark, this is my first time sending patches to clang. I'm not yet completely familiar with all clang concepts :-)

As a slight adjustment, It's probably better to just ignore this attribute when mangling the function type of an entity, the same way that we generally don't mangle return types because they don't affect overloading. That will require an extra flag to be passed down in a few places, but that's pretty reasonable. This will generally allow NS_CONSUMED and NS_RETURNS_RETAINED to be placed on existing APIs without changing their mangling unless the attribute is used in a secondary position (such as the type of an argument).

Finally, you should give ns_returns_retained the same treatment, as well as the parameter-ABI attributes.

I'm not really sure what you mean by "ignore this attribute when mangling the function type of an entity". I read this as "we should ensure that the ns_consumed attribute is only mangled if it is applied to a parameter". Is this correct?

If so, then there is nothing to do, as "ns_consumed" attibute is ignored if applied to a non-parameter type as far as I can tell (see below for compilation warning clang already emits regarding ignored attributes). So, my understanding is that the ns_consumed attribute is only used if applied to a parameter, and thus only when it is relevant to include it in the mangled name.

Regarding ns_returns_retained, it is ignored if not applied to the function itself.

$ clang++ -fobjc-arc -o x.o -c x.mm
x.mm:1:19: warning: 'ns_consumed' attribute only applies to parameters
      [-Wignored-attributes]
id __attribute__((ns_consumed)) f() { return 0; }
                  ^
x.mm:2:23: warning: 'ns_consumed' attribute only applies to parameters
      [-Wignored-attributes]
id g() __attribute__((ns_consumed)) { return 0; }
                      ^
x.mm:7:26: warning: 'ns_returns_retained' only applies to function types; type
      here is 'id' [-Wignored-attributes]
void k(id __attribute__((ns_returns_retained))) {}

So, could you elaborate a bit more on what additional changes I need to make to my patch?

This is a good catch, thanks!

Thank you for the quick reply.

Please excuse me if I misunderstood you or if my remark appear off the mark, this is my first time sending patches to clang. I'm not yet completely familiar with all clang concepts :-)

As a slight adjustment, It's probably better to just ignore this attribute when mangling the function type of an entity, the same way that we generally don't mangle return types because they don't affect overloading. That will require an extra flag to be passed down in a few places, but that's pretty reasonable. This will generally allow NS_CONSUMED and NS_RETURNS_RETAINED to be placed on existing APIs without changing their mangling unless the attribute is used in a secondary position (such as the type of an argument).

Finally, you should give ns_returns_retained the same treatment, as well as the parameter-ABI attributes.

Actually, I'm sorry, I completely failed to read your patch correctly. This is not the appropriate way to fix this problem; we do not want NS_CONSUMED to become semantically meaningful in non-ARC modes.

I'm not really sure what you mean by "ignore this attribute when mangling the function type of an entity". I read this as "we should ensure that the ns_consumed attribute is only mangled if it is applied to a parameter". Is this correct?

No. There are two reasons we mangle function types. The first is when the type appears somewhere "secondary" in the signature of the entity we're mangling, e.g. in a template argument or as the pointee type of a pointer or reference; it's important that this include all the information that distinguishes two canonically-different function types, including things like NS_CONSUMED under ARC. The second is when we're mangling the declared type of a specific function entity. It's only important that this include all the information that can distinguish overloads, and since you can't overload two functions based on whether one of them takes an NS_CONSUMED argument, this doesn't need to include those attributes. This has multiple benefits: first, it makes shorter symbols and thus saves binary size, and second, it allows the same declaration to mangle the same in both ARC and non-ARC modes as long as it doesn't feature NS_CONSUMED in a secondary position.

So I think the appropriate solution is to change the mangler to ignore things like calling conventions, NS_CONSUMED, NS_RETURNS_RETAINED, etc. when mangling the direct function type of a function entity. This will allow the same declaration to mangle the same way in ARC and non-ARC modes as long as NS_CONSUMED etc. are only used in the declaration of the function itself and not in, say, the types of its parameters.

That is, this declaration would mangle the same in both language modes:

void foo(NS_CONSUMED id x);

But this declaration would not:

void foo(void (^block)(NS_CONSUMED id x));

I think this is the best we can do, because we really don't want these attributes to have any semantic impact in non-ARC language modes. If this isn't good enough for your use case, you will need to declare the function extern "C".

So, here's what you need to do. First, don't change SemaType.cpp. Instead, you should change mangleBareFunctionType in ItaniumMangle.cpp so that it does not mangle ns_returns_retained or anything from ExtParameterInfo when FD is non-null.

Thanks, and sorry for the confusion.

sdefresne updated this revision to Diff 57924.May 20 2016, 5:11 AM
sdefresne edited edge metadata.

Ok, this make sense. I've updated my change to follow your recommendation. Can you take another look?

Using 'extern "C" { ... }" would probably not be an option in my case as I want to use "ns_consumed" for the parameter of a templated class (i.e. this probably won't work if using "C" mangling, and I'm not even sure it would compile).

That looks great, thank you.

Thank you for the comment.

I think my change still needs to be reviewed and approved by someone (at least in the Phabricator interface it still appears as "Need review"). Can you do the review and give approval if it looks good to you?

Once this is approved, should I just follow instructions at http://llvm.org/docs/Phabricator.html#subversion-and-arcanist? Do I need to request any kind of access rights?

Sorry for the questions, as I said, this is my first change against clang/llvm. Cheers,

thakis accepted this revision.May 25 2016, 7:25 AM
thakis added a reviewer: thakis.
thakis added a subscriber: thakis.

We use phabricator not very dogmatically. If John says this looks good, then this looks good, even if phab didn't get the message :-)

You do need a commit bit to land things. I've landed this change for you in r270702 (http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20160523/159820.html). http://llvm.org/docs/DeveloperPolicy.html#obtaining-commit-access documents how to obtain commit access.

This revision is now accepted and ready to land.May 25 2016, 7:25 AM
thakis closed this revision.May 25 2016, 7:25 AM