erichkeane created this revision. erichkeane added reviewers: cfe-commits, bruno, aaron.ballman, rsmith.
This is an update of this patch: https://reviews.llvm.org/D25824 I cannot seem to get that review to update with my diff. This first patch removes the dependency on isParsing and switches to isBeingDefined. In order to get that to work, changing where attributes where changed was necessary. Original description below: 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. https://reviews.llvm.org/D28266 Files: include/clang/Sema/Sema.h lib/Parse/ParseDeclCXX.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclAttr.cpp test/CodeGen/transparent-union.c test/Sema/transparent-union.c
Index: lib/Parse/ParseDeclCXX.cpp =================================================================== --- lib/Parse/ParseDeclCXX.cpp +++ lib/Parse/ParseDeclCXX.cpp @@ -1885,6 +1885,10 @@ ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get()); } + if (!TagOrTempResult.isInvalid()) + // Delayed proccessing TransparentUnion attribute. + Actions.ProcessDeclAttributeDelayed(TagOrTempResult.get(), attrs.getList()); + const char *PrevSpec = nullptr; unsigned DiagID; bool Result; Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -13477,9 +13477,6 @@ if (Invalid) New->setInvalidDecl(); - if (Attr) - ProcessDeclAttributeList(S, New, Attr); - // Set the lexical context. If the tag has a C++ scope specifier, the // lexical context will be different from the semantic context. New->setLexicalDeclContext(CurContext); @@ -13498,6 +13495,9 @@ if (TUK == TUK_Definition) New->startDefinition(); + if (Attr) + ProcessDeclAttributeList(S, New, Attr); + // If this has an identifier, add it to the scope stack. if (TUK == TUK_Friend) { // We might be replacing an existing declaration in the lookup tables; Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -3109,8 +3109,9 @@ } if (!RD->isCompleteDefinition()) { - S.Diag(Attr.getLoc(), - diag::warn_transparent_union_attribute_not_definition); + if (!RD->isBeingDefined()) + S.Diag(Attr.getLoc(), + diag::warn_transparent_union_attribute_not_definition); return; } @@ -6195,6 +6196,15 @@ } } +// Helper for delayed proccessing TransparentUnion attribute. +void Sema::ProcessDeclAttributeDelayed(Decl *D, const AttributeList *AttrList) { + for (const AttributeList* l = AttrList; l; l = l->getNext()) + if (l->getKind() == AttributeList::AT_TransparentUnion) { + handleTransparentUnionAttr(*this, D, *l); + break; + } +} + // Annotation attributes are the only attributes allowed after an access // specifier. bool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -3056,6 +3056,8 @@ void ProcessPragmaWeak(Scope *S, Decl *D); // Decl attributes - this routine is the top level dispatcher. void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD); + // Helper for delayed proccessing TransparentUnion attribute. + void ProcessDeclAttributeDelayed(Decl *D, const AttributeList *AttrList); void ProcessDeclAttributeList(Scope *S, Decl *D, const AttributeList *AL, bool IncludeCXX11Attributes = true); bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, Index: test/CodeGen/transparent-union.c =================================================================== --- test/CodeGen/transparent-union.c +++ test/CodeGen/transparent-union.c @@ -3,10 +3,21 @@ // RUN: %clang_cc1 -Werror -triple armv7-linux -emit-llvm -o - %s | FileCheck %s --check-prefix=ARM // RUN: %clang_cc1 -Werror -triple powerpc64le-linux -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -Werror -triple aarch64-linux -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DINFRONT -Werror -triple x86_64-linux -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DINFRONT -Werror -triple i386-linux -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DINFRONT -Werror -triple armv7-linux -emit-llvm -o - %s | FileCheck %s --check-prefix=ARM +// RUN: %clang_cc1 -DINFRONT -Werror -triple powerpc64le-linux -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -DINFRONT -Werror -triple aarch64-linux -emit-llvm -o - %s | FileCheck %s +#ifdef INFRONT +typedef union __attribute__((transparent_union)) { + void *f0; +} transp_t0; +#else typedef union { void *f0; } transp_t0 __attribute__((transparent_union)); +#endif void f0(transp_t0 obj); Index: test/Sema/transparent-union.c =================================================================== --- test/Sema/transparent-union.c +++ test/Sema/transparent-union.c @@ -54,11 +54,21 @@ aligned_struct8 s8; // expected-warning{{alignment of field}} } TU1 __attribute__((transparent_union)); +typedef union __attribute__((transparent_union)) { + aligned_struct4 s4; // expected-note{{alignment of first field}} + aligned_struct8 s8; // expected-warning{{alignment of field}} +} TU1b ; + typedef union { char c; // expected-note{{size of first field is 8 bits}} int i; // expected-warning{{size of field}} } TU2 __attribute__((transparent_union)); +typedef union __attribute__((transparent_union)){ + char c; // expected-note{{size of first field is 8 bits}} + int i; // expected-warning{{size of field}} +} TU2b; + typedef union { float f; // expected-warning{{floating}} } TU3 __attribute__((transparent_union)); @@ -98,3 +108,17 @@ union pr30520s { struct stb b; } __attribute__((transparent_union)); // expected-error {{field has incomplete type 'struct stb'}} union pr30520s2 { int *v; struct stb b; } __attribute__((transparent_union)); // expected-error {{field has incomplete type 'struct stb'}} + +typedef union __attribute__((__transparent_union__)) { + int *i; + struct st *s; +} TU6; + +void bar(TU6); + +void foo11(int *i) { + bar(i); +} +void foo2(struct st *s) { + bar(s); +}
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits