diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-10-28 16:55:02 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-10-28 16:55:02 +0000 |
commit | 0b350b9ec54e4fa762772688d27e38556af4f83b (patch) | |
tree | 279cf76a14690bb1fa0681bf1e9aec69d1353fbb /clang/lib/Parse/ParseDecl.cpp | |
parent | 50d634b3432dbd9f549e0243011009ddb325f8ff (diff) | |
download | bcm5719-llvm-0b350b9ec54e4fa762772688d27e38556af4f83b.tar.gz bcm5719-llvm-0b350b9ec54e4fa762772688d27e38556af4f83b.zip |
PR21367: Don't accept rvalue references as an extension in C++98 mode if we're in a new-type-id or conversion-type-id, since those things can legitimately be followed by a binary && operator.
llvm-svn: 220785
Diffstat (limited to 'clang/lib/Parse/ParseDecl.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 054df9f62fa..2288cb1c33a 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -4527,15 +4527,27 @@ void Parser::ParseDeclarator(Declarator &D) { ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator); } -static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang) { +static bool isPtrOperatorToken(tok::TokenKind Kind, const LangOptions &Lang, + unsigned TheContext) { if (Kind == tok::star || Kind == tok::caret) return true; - // We parse rvalue refs in C++03, because otherwise the errors are scary. if (!Lang.CPlusPlus) return false; - return Kind == tok::amp || Kind == tok::ampamp; + if (Kind == tok::amp) + return true; + + // We parse rvalue refs in C++03, because otherwise the errors are scary. + // But we must not parse them in conversion-type-ids and new-type-ids, since + // those can be legitimately followed by a && operator. + // (The same thing can in theory happen after a trailing-return-type, but + // since those are a C++11 feature, there is no rejects-valid issue there.) + if (Kind == tok::ampamp) + return Lang.CPlusPlus11 || (TheContext != Declarator::ConversionIdContext && + TheContext != Declarator::CXXNewContext); + + return false; } /// ParseDeclaratorInternal - Parse a C or C++ declarator. The direct-declarator @@ -4615,7 +4627,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D, tok::TokenKind Kind = Tok.getKind(); // Not a pointer, C++ reference, or block. - if (!isPtrOperatorToken(Kind, getLangOpts())) { + if (!isPtrOperatorToken(Kind, getLangOpts(), D.getContext())) { if (DirectDeclParser) (this->*DirectDeclParser)(D); return; @@ -4810,7 +4822,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) { !D.hasGroupingParens() && !Actions.containsUnexpandedParameterPacks(D))) { SourceLocation EllipsisLoc = ConsumeToken(); - if (isPtrOperatorToken(Tok.getKind(), getLangOpts())) { + if (isPtrOperatorToken(Tok.getKind(), getLangOpts(), D.getContext())) { // The ellipsis was put in the wrong place. Recover, and explain to // the user what they should have done. ParseDeclarator(D); |