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