diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-01-08 00:56:48 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-01-08 00:56:48 +0000 |
commit | 649c7b069f53596e2c651d6524cf7c6621e3d565 (patch) | |
tree | 843dea1c8f456052afad31c30fa10dcf7f0eb6b1 /clang/lib/Sema | |
parent | 1c3996abc7201af3e2041527a3e1fb3d4d4774c1 (diff) | |
download | bcm5719-llvm-649c7b069f53596e2c651d6524cf7c6621e3d565.tar.gz bcm5719-llvm-649c7b069f53596e2c651d6524cf7c6621e3d565.zip |
PR18234: Mark a tag definition as invalid early if it appears in a
type-specifier in C++. Some checks will assert in this case otherwise (in
particular, the access specifier may be missing if this happens inside a class
definition, due to a violation of an AST invariant).
llvm-svn: 198721
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 14 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 3 |
3 files changed, 20 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 07a551da2f1..7cdf81a87e4 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -10396,6 +10396,9 @@ bool Sema::isAcceptableTagRedeclaration(const TagDecl *Previous, /// former case, Name will be non-null. In the later case, Name will be null. /// TagSpec indicates what kind of tag this is. TUK indicates whether this is a /// reference/declaration/definition of a tag. +/// +/// IsTypeSpecifier is true if this is a type-specifier (or +/// trailing-type-specifier) other than one in an alias-declaration. Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, @@ -10405,7 +10408,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, bool &OwnedDecl, bool &IsDependent, SourceLocation ScopedEnumKWLoc, bool ScopedEnumUsesClassTag, - TypeResult UnderlyingType) { + TypeResult UnderlyingType, + bool IsTypeSpecifier) { // If this is not a definition, it must have a name. IdentifierInfo *OrigName = Name; assert((Name != 0 || TUK == TUK_Definition) && @@ -11016,6 +11020,14 @@ CreateNewDecl: cast_or_null<RecordDecl>(PrevDecl)); } + // C++11 [dcl.type]p3: + // A type-specifier-seq shall not define a class or enumeration [...]. + if (getLangOpts().CPlusPlus && IsTypeSpecifier && TUK == TUK_Definition) { + Diag(New->getLocation(), diag::err_type_defined_in_type_specifier) + << Context.getTagDeclType(New); + Invalid = true; + } + // Maybe add qualifier info. if (SS.isNotEmpty()) { if (SS.isSet()) { diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 91b9c6a5880..28f038a69e3 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -11460,14 +11460,15 @@ Decl *Sema::ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc, bool Owned = false; bool IsDependent = false; return ActOnTag(S, TagSpec, TUK_Friend, TagLoc, SS, Name, NameLoc, - Attr, AS_public, + Attr, AS_public, /*ModulePrivateLoc=*/SourceLocation(), - MultiTemplateParamsArg(), Owned, IsDependent, + MultiTemplateParamsArg(), Owned, IsDependent, /*ScopedEnumKWLoc=*/SourceLocation(), /*ScopedEnumUsesClassTag=*/false, - /*UnderlyingType=*/TypeResult()); + /*UnderlyingType=*/TypeResult(), + /*IsTypeSpecifier=*/false); } - + NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context); ElaboratedTypeKeyword Keyword = TypeWithKeyword::getKeywordForTagTypeKind(Kind); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 4f050345bc8..b468e31f097 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -7101,7 +7101,8 @@ Sema::ActOnExplicitInstantiation(Scope *S, KWLoc, SS, Name, NameLoc, Attr, AS_none, /*ModulePrivateLoc=*/SourceLocation(), MultiTemplateParamsArg(), Owned, IsDependent, - SourceLocation(), false, TypeResult()); + SourceLocation(), false, TypeResult(), + /*IsTypeSpecifier*/false); assert(!IsDependent && "explicit instantiation of dependent name not yet handled"); if (!TagD) |