summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2015-02-15 07:26:13 +0000
committerNico Weber <nicolasweber@gmx.de>2015-02-15 07:26:13 +0000
commitcfaa4cdc35c0b21fb6cef140615007f5782ae127 (patch)
treea1199cabf627be614528af619a2ffc8716aa76a5 /clang/lib/Parse/ParseDecl.cpp
parent78c424dfca9ac7b8ffb94d066771c23295d53427 (diff)
downloadbcm5719-llvm-cfaa4cdc35c0b21fb6cef140615007f5782ae127.tar.gz
bcm5719-llvm-cfaa4cdc35c0b21fb6cef140615007f5782ae127.zip
Don't crash on `struct ::, struct ::` (and the same for enums).
The first part of that line doesn't parse correctly and ParseClassSpecifier() for some reason skips to tok::comma to recover, and then ParseDeclarationSpecifiers() sees the next struct and calls ParseClassSpecifier() again with the same DeclSpec object. However, the first call already called ActOnCXXGlobalScopeSpecifier() on the DeclSpec's CXXScopeSpec, and sema gets confused when this gets called again. As a fix, let ParseClassSpecifier() (and ParseEnumSpecifier()) call ParseOptionalCXXScopeSpec() with a temporary CXXScopeSpec object, and only copy it into the DeclSpec if things work out. (This is also how all the other functions that set the DeclSpec's TypeSpecScope set it.) Found by SLi's bot. llvm-svn: 229288
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r--clang/lib/Parse/ParseDecl.cpp7
1 files changed, 5 insertions, 2 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 8fcfcb34be2..a17fd6dbee8 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -3648,11 +3648,12 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
// if a fixed underlying type is allowed.
ColonProtectionRAIIObject X(*this, AllowFixedUnderlyingType);
- if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
+ CXXScopeSpec Spec;
+ if (ParseOptionalCXXScopeSpecifier(Spec, ParsedType(),
/*EnteringContext=*/true))
return;
- if (SS.isSet() && Tok.isNot(tok::identifier)) {
+ if (Spec.isSet() && Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_expected) << tok::identifier;
if (Tok.isNot(tok::l_brace)) {
// Has no name and is not a definition.
@@ -3661,6 +3662,8 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
return;
}
}
+
+ SS = Spec;
}
// Must have either 'enum name' or 'enum {...}'.
OpenPOWER on IntegriCloud