diff options
author | Nico Weber <nicolasweber@gmx.de> | 2015-02-16 22:32:46 +0000 |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2015-02-16 22:32:46 +0000 |
commit | c60aa71aa2892b5aa64b303109b29725b1b4aa94 (patch) | |
tree | 013f483b2a41fb488a54771f2d8ec7c8772becc4 /clang/lib/Parse/ParseExprCXX.cpp | |
parent | bf2b90e92d6be234ac5eca7707a51b3d9107d91c (diff) | |
download | bcm5719-llvm-c60aa71aa2892b5aa64b303109b29725b1b4aa94.tar.gz bcm5719-llvm-c60aa71aa2892b5aa64b303109b29725b1b4aa94.zip |
For variables with dependent type, don't crash on `var->::new` or `var->__super`
ParsePostfixExpressionSuffix() for '->' (or '.') postfixes first calls
ActOnStartCXXMemberReference() to inform sema that a member reference is about
to start, and that function lets the parser know if sema thinks that the
base expression's type could allow a pseudo destructor from a semantic point of
view (for example, if the the base expression has a dependent type).
ParsePostfixExpressionSuffix() then calls ParseOptionalCXXScopeSpecifier() and
passes MayBePseudoDestructor on to that function, expecting the function to
set it to false if a pseudo destructor is impossible from a syntactic point of
view (due to a lack of '~' sigil). However, ParseOptionalCXXScopeSpecifier()
had early-outs for ::new and __super, so MayBePseudoDestructor stayed true,
so we tried to parse a pseudo dtor, and then became confused since we couldn't
find a '~'. Move the snippet in ParseOptionalCXXScopeSpecifier() that sets
MayBePseudoDestructor to false above the early exits.
Parts of this found by SLi's bot.
llvm-svn: 229449
Diffstat (limited to 'clang/lib/Parse/ParseExprCXX.cpp')
-rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index e7ca66de487..d91744115cc 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -194,6 +194,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, if (Tok.is(tok::annot_cxxscope)) { assert(!LastII && "want last identifier but have already annotated scope"); + assert(!MayBePseudoDestructor && "unexpected annot_cxxscope"); Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(), Tok.getAnnotationRange(), SS); @@ -208,6 +209,13 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, SS = TemplateId->SS; } + // Has to happen before any "return false"s in this function. + bool CheckForDestructor = false; + if (MayBePseudoDestructor && *MayBePseudoDestructor) { + CheckForDestructor = true; + *MayBePseudoDestructor = false; + } + if (LastII) *LastII = nullptr; @@ -244,12 +252,6 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, return Actions.ActOnSuperScopeSpecifier(SuperLoc, ConsumeToken(), SS); } - bool CheckForDestructor = false; - if (MayBePseudoDestructor && *MayBePseudoDestructor) { - CheckForDestructor = true; - *MayBePseudoDestructor = false; - } - if (!HasScopeSpecifier && (Tok.is(tok::kw_decltype) || Tok.is(tok::annot_decltype))) { DeclSpec DS(AttrFactory); |