summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-01-08 00:56:48 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-01-08 00:56:48 +0000
commit649c7b069f53596e2c651d6524cf7c6621e3d565 (patch)
tree843dea1c8f456052afad31c30fa10dcf7f0eb6b1 /clang/lib/Sema/SemaDecl.cpp
parent1c3996abc7201af3e2041527a3e1fb3d4d4774c1 (diff)
downloadbcm5719-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/SemaDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp14
1 files changed, 13 insertions, 1 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()) {
OpenPOWER on IntegriCloud