Hi rsmith, doug.gregor,

This fixes PR23931 .
I'm not entirely sure about the words of the error message.

REPOSITORY
  rL LLVM

http://reviews.llvm.org/D10752

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaDecl.cpp
  test/SemaCXX/virtual-function-in-union.cpp

Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -1262,6 +1262,8 @@
 def err_mutable_const : Error<"'mutable' and 'const' cannot be mixed">;
 def err_mutable_nonmember : Error<
   "'mutable' can only be applied to member variables">;
+def err_virtual_in_union : Error<
+  "function %0 declared 'virtual' within a union">;
 def err_virtual_non_function : Error<
   "'virtual' can only appear on non-static member functions">;
 def err_virtual_out_of_class : Error<
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -7202,6 +7202,14 @@
           dyn_cast<CXXRecordDecl>(NewFD->getDeclContext())) {
       if (Parent->isInterface() && 
cast<CXXMethodDecl>(NewFD)->isUserProvided())
         NewFD->setPure(true);
+
+      // C++ [class.union]p2
+      //   A union can have member functions, but not virtual functions.
+      if (isVirtual && Parent->isUnion()) {
+        Diag(D.getDeclSpec().getVirtualSpecLoc(),
+            diag::err_virtual_in_union) << NewFD->getDeclName();
+        NewFD->setInvalidDecl();
+      }
     }
 
     SetNestedNameSpecifier(NewFD, D);
Index: test/SemaCXX/virtual-function-in-union.cpp
===================================================================
--- test/SemaCXX/virtual-function-in-union.cpp
+++ test/SemaCXX/virtual-function-in-union.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+union x {
+  virtual void f(); // expected-error {{function 'f' declared 'virtual' within 
a union}}
+};

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -1262,6 +1262,8 @@
 def err_mutable_const : Error<"'mutable' and 'const' cannot be mixed">;
 def err_mutable_nonmember : Error<
   "'mutable' can only be applied to member variables">;
+def err_virtual_in_union : Error<
+  "function %0 declared 'virtual' within a union">;
 def err_virtual_non_function : Error<
   "'virtual' can only appear on non-static member functions">;
 def err_virtual_out_of_class : Error<
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -7202,6 +7202,14 @@
           dyn_cast<CXXRecordDecl>(NewFD->getDeclContext())) {
       if (Parent->isInterface() && cast<CXXMethodDecl>(NewFD)->isUserProvided())
         NewFD->setPure(true);
+
+      // C++ [class.union]p2
+      //   A union can have member functions, but not virtual functions.
+      if (isVirtual && Parent->isUnion()) {
+        Diag(D.getDeclSpec().getVirtualSpecLoc(),
+            diag::err_virtual_in_union) << NewFD->getDeclName();
+        NewFD->setInvalidDecl();
+      }
     }
 
     SetNestedNameSpecifier(NewFD, D);
Index: test/SemaCXX/virtual-function-in-union.cpp
===================================================================
--- test/SemaCXX/virtual-function-in-union.cpp
+++ test/SemaCXX/virtual-function-in-union.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+union x {
+  virtual void f(); // expected-error {{function 'f' declared 'virtual' within a union}}
+};
_______________________________________________
cfe-commits mailing list
cfe-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to