[PATCH] D80295: [Sema] Diagnose static data members in classes nested in unnamed classes
John Brawn via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu May 21 06:26:48 PDT 2020
john.brawn updated this revision to Diff 265486.
john.brawn marked an inline comment as done.
john.brawn added a comment.
Use the tag of the anonymous struct when emitting a diagnostic.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D80295/new/
https://reviews.llvm.org/D80295
Files:
clang/lib/Sema/SemaDecl.cpp
clang/test/SemaCXX/anonymous-struct.cpp
Index: clang/test/SemaCXX/anonymous-struct.cpp
===================================================================
--- clang/test/SemaCXX/anonymous-struct.cpp
+++ clang/test/SemaCXX/anonymous-struct.cpp
@@ -153,3 +153,21 @@
const Empty E;
} C;
} // namespace ImplicitDecls
+
+struct {
+ static int x; // expected-error {{static data member 'x' not allowed in anonymous struct}}
+} static_member_1;
+
+class {
+ struct A {
+ static int x; // expected-error {{static data member 'x' not allowed in anonymous class}}
+ } x;
+} static_member_2;
+
+union {
+ struct A {
+ struct B {
+ static int x; // expected-error {{static data member 'x' not allowed in anonymous union}}
+ } x;
+ } x;
+} static_member_3;
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -6885,19 +6885,29 @@
if (SC == SC_Static && CurContext->isRecord()) {
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC)) {
- // C++ [class.static.data]p2:
- // A static data member shall not be a direct member of an unnamed
- // or local class
- // FIXME: or of a (possibly indirectly) nested class thereof.
- if (RD->isLocalClass()) {
- Diag(D.getIdentifierLoc(),
- diag::err_static_data_member_not_allowed_in_local_class)
- << Name << RD->getDeclName() << RD->getTagKind();
- } else if (!RD->getDeclName()) {
+ const CXXRecordDecl *AnonStruct = nullptr;
+ for (DeclContext *Ctxt = DC;
+ const CXXRecordDecl *ParentDecl = dyn_cast<CXXRecordDecl>(Ctxt);
+ Ctxt = Ctxt->getParent()) {
+ if (!ParentDecl->getDeclName()) {
+ AnonStruct = ParentDecl;
+ break;
+ }
+ }
+ if (AnonStruct) {
+ // C++ [class.static.data]p4: Unnamed classes and classes contained
+ // directly or indirectly within unnamed classes shall not contain
+ // static data members.
Diag(D.getIdentifierLoc(),
diag::err_static_data_member_not_allowed_in_anon_struct)
- << Name << RD->getTagKind();
+ << Name << AnonStruct->getTagKind();
Invalid = true;
+ } else if (RD->isLocalClass()) {
+ // C++ [class.static.data]p5: A local class shall not have static data
+ // members.
+ Diag(D.getIdentifierLoc(),
+ diag::err_static_data_member_not_allowed_in_local_class)
+ << Name << RD->getDeclName() << RD->getTagKind();
} else if (RD->isUnion()) {
// C++98 [class.union]p1: If a union contains a static data member,
// the program is ill-formed. C++11 drops this restriction.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D80295.265486.patch
Type: text/x-patch
Size: 2806 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200521/dccbcf83/attachment-0001.bin>
More information about the cfe-commits
mailing list