From 3343fad1f1ec81af43674b76eddbe9ab10e344eb Mon Sep 17 00:00:00 2001
From: Richard Smith
Date: Fri, 23 Mar 2012 23:09:08 +0000
Subject: [PATCH] When defining a forward-declared enum, don't try to attach
the definition to a previous declaration if the redeclaration is invalid.
That way lies madness. Fixes a crash-on-invalid reported by Abramo.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153349 91177308-0d34-0410-b5e6-96231b3b80d8
---
docs/ReleaseNotes.html | 1 +
include/clang/Basic/DiagnosticSemaKinds.td | 2 ++
lib/Sema/SemaDecl.cpp | 5 +++--
lib/Sema/SemaTemplateInstantiate.cpp | 3 ++-
test/SemaCXX/enum-scoped.cpp | 11 +++++++++++
www/cxx_status.html | 2 +-
6 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/docs/ReleaseNotes.html b/docs/ReleaseNotes.html
index 628079978e..64c6acb25a 100644
--- a/docs/ReleaseNotes.html
+++ b/docs/ReleaseNotes.html
@@ -125,6 +125,7 @@ following are now considered to be of production quality:
Generalized initializers
Unrestricted unions
User-defined literals
+ Forward-declared enumerations
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 36232b1e98..405ae906e5 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1276,6 +1276,8 @@ def err_enum_class_reference : Error<
"not 'enum class'">;
def err_only_enums_have_underlying_types : Error<
"only enumeration types have underlying types">;
+def err_unscoped_enum_defined_out_of_class : Error<
+ "out-of-line definition of unscoped enumeration member is not supported">;
// C++11 delegating constructors
def err_delegating_ctor : Error<
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 71f567f47a..68b27ef1f9 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -8260,10 +8260,11 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
EnumUnderlyingTy = QualType(T, 0);
// All conflicts with previous declarations are recovered by
- // returning the previous declaration.
+ // returning the previous declaration, unless this is a definition,
+ // in which case we want the caller to bail out.
if (CheckEnumRedeclaration(NameLoc.isValid() ? NameLoc : KWLoc,
ScopedEnum, EnumUnderlyingTy, PrevEnum))
- return PrevTagDecl;
+ return TUK == TUK_Declaration ? PrevTagDecl : 0;
}
if (!Invalid) {
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index afa65ea9ee..307cccce8b 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1848,7 +1848,8 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
// specialization causes the implicit instantiation of the definitions
// of unscoped member enumerations.
// Record a point of instantiation for this implicit instantiation.
- if (TSK == TSK_ImplicitInstantiation && !Enum->isScoped()) {
+ if (TSK == TSK_ImplicitInstantiation && !Enum->isScoped() &&
+ Enum->isCompleteDefinition()) {
MemberSpecializationInfo *MSInfo =Enum->getMemberSpecializationInfo();
assert(MSInfo && "no spec info for member enum specialization");
MSInfo->setTemplateSpecializationKind(TSK_ImplicitInstantiation);
diff --git a/test/SemaCXX/enum-scoped.cpp b/test/SemaCXX/enum-scoped.cpp
index 31190bebaa..44394296e3 100644
--- a/test/SemaCXX/enum-scoped.cpp
+++ b/test/SemaCXX/enum-scoped.cpp
@@ -189,3 +189,14 @@ namespace test7 {
enum class E { e = (struct S*)0 == (struct S*)0 };
S *p;
}
+
+namespace test8 {
+ template struct S {
+ enum A : int; // expected-note {{here}}
+ enum class B; // expected-note {{here}}
+ enum class C : int; // expected-note {{here}}
+ };
+ template enum S::A { a }; // expected-error {{previously declared with fixed underlying type}}
+ template enum class S::B : char { b }; // expected-error {{redeclared with different underlying}}
+ template enum S::C : int { c }; // expected-error {{previously declared as scoped}}
+}
diff --git a/www/cxx_status.html b/www/cxx_status.html
index 28da5f096b..8305b73ec6 100644
--- a/www/cxx_status.html
+++ b/www/cxx_status.html
@@ -158,7 +158,7 @@ with clang; other versions have not been tested.
Forward declarations for enums |
N2764
DR1206 |
- No |
+ SVN |
Generalized attributes |
--
2.50.1