arphaman created this revision. arphaman added reviewers: rnk, aaron.ballman. arphaman added a subscriber: cfe-commits. arphaman set the repository for this revision to rL LLVM.
While working on fixing PR30520 yesterday I noticed that clang also crashes on code like this: template<typename T> union u { T b; } __attribute__((transparent_union)); I mentioned in https://reviews.llvm.org/D25273 that I plan on fixing it properly by instantiating the attribute, but, after looking more into it, I discovered that we don't really support 'transparent_union' in C++ at all. This is why I decided to go with the approach that's presented in this patch: the attribute is completely ignored when clang is in C++ mode, and thus the crash is avoided. I wasn't sure if we should we emit an error or a warning when ignoring this attribute and if we need any diagnostics in Gnu mode at all. That's why in this initial patch doesn't emit a diagnostic when ignoring this attribute. Please let me know whether we need to show one or not. Thanks Repository: rL LLVM https://reviews.llvm.org/D25308 Files: lib/Sema/SemaDeclAttr.cpp test/SemaCXX/attr-gnu.cpp Index: test/SemaCXX/attr-gnu.cpp =================================================================== --- test/SemaCXX/attr-gnu.cpp +++ test/SemaCXX/attr-gnu.cpp @@ -27,3 +27,19 @@ void test3() __attribute__((cf_unknown_transfer)) override {} // Ok, not known to GCC. }; } + +template<typename T> +union Tu { T b; } __attribute__((transparent_union)); + +template<typename T> +union Tu2 { int x; T b; } __attribute__((transparent_union)); + +union Tu3 { int x; } __attribute((transparent_union)); + +void tuTest1(Tu<int> u); // expected-note {{candidate function not viable: no known conversion from 'int' to 'Tu<int>' for 1st argument}} +void tuTest2(Tu3 u); // expected-note {{candidate function not viable: no known conversion from 'int' to 'Tu3' for 1st argument}} +void tu() { + int x = 2; + tuTest1(x); // expected-error {{no matching function for call to 'tuTest1'}} + tuTest2(x); // expected-error {{no matching function for call to 'tuTest2'}} +} Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -3008,6 +3008,10 @@ static void handleTransparentUnionAttr(Sema &S, Decl *D, const AttributeList &Attr) { + if (S.getLangOpts().CPlusPlus) { + return; + } + // Try to find the underlying union declaration. RecordDecl *RD = nullptr; TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
Index: test/SemaCXX/attr-gnu.cpp =================================================================== --- test/SemaCXX/attr-gnu.cpp +++ test/SemaCXX/attr-gnu.cpp @@ -27,3 +27,19 @@ void test3() __attribute__((cf_unknown_transfer)) override {} // Ok, not known to GCC. }; } + +template<typename T> +union Tu { T b; } __attribute__((transparent_union)); + +template<typename T> +union Tu2 { int x; T b; } __attribute__((transparent_union)); + +union Tu3 { int x; } __attribute((transparent_union)); + +void tuTest1(Tu<int> u); // expected-note {{candidate function not viable: no known conversion from 'int' to 'Tu<int>' for 1st argument}} +void tuTest2(Tu3 u); // expected-note {{candidate function not viable: no known conversion from 'int' to 'Tu3' for 1st argument}} +void tu() { + int x = 2; + tuTest1(x); // expected-error {{no matching function for call to 'tuTest1'}} + tuTest2(x); // expected-error {{no matching function for call to 'tuTest2'}} +} Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -3008,6 +3008,10 @@ static void handleTransparentUnionAttr(Sema &S, Decl *D, const AttributeList &Attr) { + if (S.getLangOpts().CPlusPlus) { + return; + } + // Try to find the underlying union declaration. RecordDecl *RD = nullptr; TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D);
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits