summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--clang/lib/Sema/SemaDecl.cpp5
-rw-r--r--clang/test/SemaCXX/virtual-function-in-union.cpp5
3 files changed, 12 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 36068e24c90..4448b3d7484 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1262,6 +1262,8 @@ def ext_mutable_reference : ExtWarn<
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<
+ "unions cannot have virtual functions">;
def err_virtual_non_function : Error<
"'virtual' can only appear on non-static member functions">;
def err_virtual_out_of_class : Error<
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 19bc7f99c8c..ae97b24f853 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -7202,6 +7202,11 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
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);
}
SetNestedNameSpecifier(NewFD, D);
diff --git a/clang/test/SemaCXX/virtual-function-in-union.cpp b/clang/test/SemaCXX/virtual-function-in-union.cpp
new file mode 100644
index 00000000000..0c4ba5d32ca
--- /dev/null
+++ b/clang/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 {{unions cannot have virtual functions}}
+};
OpenPOWER on IntegriCloud