This is an archive of the discontinued LLVM Phabricator instance.

Transparent_union attribute should be possible in front of union.
AbandonedPublic

Authored by erichkeane on Oct 20 2016, 6:49 AM.

Details

Summary

Clang compiles with error following test case

typedef union attribute((transparent_union)) {

int *i;
struct st *s;

} TU;

void bar(TU);

void foo(int *i) {

bar(i);

}

clang -c tu.c
tu.c:1:30: warning: transparent_union attribute can only be applied to a union definition; attribute ignored [-Wignored-attributes]
typedef union attribute((transparent_union)) {

^

tu.c:8:24: error: passing 'int *' to parameter of incompatible type 'TU'
void foo(int *i) { bar(i); }

^

tu.c:6:12: note: passing argument to parameter here
void bar(TU);

^

GCC compiles this test successfully.

The compilation is failed because the routine handleTransparentUnionAttr requires for the record decl to be completed. This fix provides handling of the attribute ‘transparent_union’ after parsing of union.

Diff Detail

Event Timeline

vbyakovlcl updated this revision to Diff 75289.Oct 20 2016, 6:49 AM
vbyakovlcl retitled this revision from to Transparent_union attribute should be possible in front of union..
vbyakovlcl updated this object.
vbyakovlcl added reviewers: aaron.ballman, bruno.
vbyakovlcl set the repository for this revision to rL LLVM.
aaron.ballman requested changes to this revision.Oct 31 2016, 7:17 AM
aaron.ballman edited edge metadata.
aaron.ballman added inline comments.
llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp
3011

All of the handle*Attr() functions should have a uniform signature (there are plans for automating more attribute handling code), so you should find a way to implement this that does not require modifying the handler signature (or threading that information through ProcessDeclAttribute()).

This revision now requires changes to proceed.Oct 31 2016, 7:17 AM
vbyakovlcl updated this revision to Diff 76555.Nov 1 2016, 7:53 AM
vbyakovlcl edited edge metadata.
vbyakovlcl removed rL LLVM as the repository for this revision.
vbyakovlcl added inline comments.Nov 17 2016, 2:42 AM
llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp
3011

I did changes you asked two weeks ago. I'm waiting a review of the changes.

An interesting thing to note is that another implementation of this attribute (from IBM) is also explicit about requiring the type to be complete: http://www.ibm.com/support/knowledgecenter/SSGH2K_13.1.0/com.ibm.xlc131.aix.doc/language_ref/type_attr_transp_union.html

Out of curiosity, is this a common use of the feature that is required by some library headers? I kind of wonder if GCC gets around this by not checking the calling conventions for the union members at all. For instance, Clang compiles this, but GCC claims the union cannot be made transparent:

union TU2 {
  _Alignas(128) int *i;
  _Alignas(128) struct st *s;
} __attribute__((__transparent_union__));

void baz(union TU2);

void foo(int *i) {
  baz(i);
}

Adding Richard Smith, in case he has thoughts or ideas. I admit that I'm not overly familiar with this attribute, but the fact that two implementations agree that the union must be complete makes me wonder if this is an explicit feature of GCC or not.

llvm/tools/clang/include/clang/AST/DeclBase.h
284 ↗(On Diff #76555)

This comment is a bit unclear. What does it mean for a declaration to be "parsing"?

llvm/tools/clang/lib/Sema/SemaDecl.cpp
13295 ↗(On Diff #76555)

This does not seem like a particularly clean way to solve this problem. It's a bit strange for some part of the semantics engine to claim a declaration is currently being parsed, and it's fragile that the only way to set that it is no longer being parsed is when processing the attribute list.

13298 ↗(On Diff #76555)

No need to pass true here as it defaults to true already.

llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp
3011

Sorry about the delayed response; I've been on vacation for the past while and did not have Internet access.

vbyakovlcl updated this revision to Diff 82327.Dec 22 2016, 3:55 AM
vbyakovlcl added a reviewer: erichkeane.

December 27 is my last day at Intel. I added a reviewer Erich Keane to finish the work if I will not able to do it.

llvm/tools/clang/include/clang/AST/DeclBase.h
284 ↗(On Diff #76555)

Fixed

llvm/tools/clang/lib/Sema/SemaDecl.cpp
13295 ↗(On Diff #76555)

To fix problem we need to handle the transparent_union attribute after the declaration parsing is finished. In the previous reduction I passed a boolean argument to handleTransparentUnionAttr to say that it needs to delay the attribute handling. Now I simple pass this flag via a Decl field. I don't see what problem can be here.

13298 ↗(On Diff #76555)

Fxed

rsmith requested changes to this revision.Dec 22 2016, 2:31 PM
rsmith edited edge metadata.
rsmith added inline comments.
llvm/tools/clang/include/clang/AST/DeclBase.h
287–288 ↗(On Diff #82327)

It's not OK to add a bit here and make all declarations 8 bytes larger.

You also don't need this -- TagDecl::IsBeingDefined already carries the information you want here. It's possible that we don't set that flag quite early enough, but we can fix that if necessary, by slightly deferring when we process attributes in the parser.

Alternatively, we could defer processing attributes on a tag definition (in the parser) until after we've handled the tag definition.

This revision now requires changes to proceed.Dec 22 2016, 2:31 PM
erichkeane edited edge metadata.Jan 9 2017, 9:09 AM

It hasn't received any attention, but I've put the rework of this patch into the review here: https://reviews.llvm.org/D28266. The patch fixes all the compliants mentioned here.

I suspect that this one can be closed.

-Erich

vbyakovlcl updated this revision to Diff 83653.Jan 9 2017, 10:55 AM
vbyakovlcl edited edge metadata.
vbyakovlcl added inline comments.
llvm/tools/clang/include/clang/AST/DeclBase.h
287–288 ↗(On Diff #82327)

I also prepared changes using TagDecl::IsBeingDefined which quite similar to Erich did. Please change which is better.

I don't believe this will work correctly, the change I made in mine to SemaDecl.cpp is necessary, otherwise the ProcessDeclAttributeList will be called with out isBeingDefined properly set.

llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp
3196

Why bother with the downcast? RD is a RecordDecl which inherits from TagDecl.

vbyakovlcl updated this revision to Diff 83655.Jan 9 2017, 11:02 AM
vbyakovlcl edited edge metadata.
vbyakovlcl added inline comments.Jan 9 2017, 11:20 AM
llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp
3196

You are right.

vbyakovlcl updated this revision to Diff 83659.Jan 9 2017, 11:20 AM
erichkeane added inline comments.Jan 9 2017, 11:22 AM
llvm/tools/clang/lib/Sema/SemaDeclAttr.cpp
3196–3199

See my overall comment earlier, I think that the change to SemaDecl.cpp is necessary, otherwise 'isBeingDefined' will always be false here.

erichkeane commandeered this revision.Jun 2 2017, 10:37 AM
erichkeane edited reviewers, added: vbyakovlcl; removed: erichkeane.
erichkeane edited edge metadata.

Did this in a separate review.

This revision now requires changes to proceed.Jun 2 2017, 10:37 AM
erichkeane abandoned this revision.Jun 2 2017, 10:37 AM

done separately