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

Reply via email to