summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-10-28 16:55:02 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-10-28 16:55:02 +0000
commit0b350b9ec54e4fa762772688d27e38556af4f83b (patch)
tree279cf76a14690bb1fa0681bf1e9aec69d1353fbb /clang/lib/Parse/ParseDecl.cpp
parent50d634b3432dbd9f549e0243011009ddb325f8ff (diff)
downloadbcm5719-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.cpp22
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);
OpenPOWER on IntegriCloud