This is an archive of the discontinued LLVM Phabricator instance.

make attribute instantiation instantiate all attributes
ClosedPublic

Authored by rsmith on Jan 4 2018, 11:13 AM.

Details

Summary

Attribute instantiation would previously default to instantiating each kind of attribute only once. This was overridden by a flag whose intended purpose was to permit attributes from a prior declaration to be inherited onto a new declaration even if that new declaration had its own copy of the attribute. This appears to be the wrong behavior: when instantiating attributes from a template, we should always instantiate all the attributes that were written on that template.

This patch renames the flag in the Attr class (and TableGen sources) to more clearly identify what it's actually for, and removes the usage of the flag from template instantiation. I also removed the flag from AlignedAttr, which was only added to work around the seemingly-incorrect suppression of duplicate attribute instantiation.

Diff Detail

Repository
rC Clang

Event Timeline

rsmith created this revision.Jan 4 2018, 11:13 AM

Presumably this didn't break any tests, so I'm Ok with it. The initial patch was to make sure that template specializations could clear certain attributes, so I think this properly gets that done. The below test was apparently missed in the initial patch (and was the reason for the revert/restore), so perhaps this is something that could be validated still works as well. See comments here: https://reviews.llvm.org/rL298410

class Mutex {
public:

void Lock() __attribute__((exclusive_lock_function()));
void Unlock() __attribute__((unlock_function()));

};

class A {
public:

Mutex mu1, mu2;

void foo() __attribute__((exclusive_locks_required(mu1))) __attribute__((exclusive_locks_required(mu2))) {}

template <class T> void bar() __attribute__((exclusive_locks_required(mu1))) __attribute__((exclusive_locks_required(mu2))) {
  foo();
}

};

void f() {

A a;
a.mu1.Lock();
a.mu2.Lock();
a.bar<int>();
a.mu2.Unlock();
a.mu1.Unlock();

}

I don't suppose there is a chance at test coverage for this change?

include/clang/AST/Attr.h
142

I'm not too keen on the name -- perhaps isInheritedEvenIfAlreadyPresent()?

rsmith updated this revision to Diff 128654.Jan 4 2018, 2:37 PM
rsmith added a comment.Jan 4 2018, 2:39 PM

I don't suppose there is a chance at test coverage for this change?

Added Erich's test, plus a test that all instances of another attribute (annotate) get instantiated (the latter test failed prior to this change).

include/clang/AST/Attr.h
142

I started with that, but then changed to this abomination because isInherited[...] suggests it's telling you whether this attribute was inherited (like isInherited() does), which is not what it's for.

How about shouldInheritEvenIfAlreadyPresent?

LGTM, I like the shouldInheritEvenIfAlreadyPresent name better than isInherited... FWIW. I'll let @aaron.ballman make the final call though.

aaron.ballman accepted this revision.Jan 4 2018, 3:26 PM

LGTM, thank you!

include/clang/AST/Attr.h
142

Sold!

This revision is now accepted and ready to land.Jan 4 2018, 3:26 PM
rsmith closed this revision.Jan 4 2018, 3:43 PM

Committed as r321834.