diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-05-15 02:43:47 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-05-15 02:43:47 +0000 |
commit | ae2d06735fec992d61c44cf531984e5ffc7e67d1 (patch) | |
tree | e0992751f5c71b4c19bf4ba7138d1672a4bccea5 | |
parent | 89a69a81af1a840e00a54c7ce303f546f89d0cba (diff) | |
download | clang-ae2d06735fec992d61c44cf531984e5ffc7e67d1.tar.gz clang-ae2d06735fec992d61c44cf531984e5ffc7e67d1.tar.bz2 clang-ae2d06735fec992d61c44cf531984e5ffc7e67d1.tar.xz |
PR19748: Make sure we don't lose colon protection after the parenthesized type-id in a cast-expression.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@208843 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Parse/Parser.h | 6 | ||||
-rw-r--r-- | lib/Parse/ParseExpr.cpp | 17 | ||||
-rw-r--r-- | lib/Parse/ParseExprCXX.cpp | 15 | ||||
-rw-r--r-- | test/Parser/cxx-casting.cpp | 11 |
4 files changed, 32 insertions, 17 deletions
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 79c65c6db4..57adf9d385 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -1391,9 +1391,9 @@ private: ParsedType &CastTy, SourceLocation &RParenLoc); - ExprResult ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, - ParsedType &CastTy, - BalancedDelimiterTracker &Tracker); + ExprResult ParseCXXAmbiguousParenExpression( + ParenParseOption &ExprType, ParsedType &CastTy, + BalancedDelimiterTracker &Tracker, ColonProtectionRAIIObject &ColonProt); ExprResult ParseCompoundLiteralExpression(ParsedType Ty, SourceLocation LParenLoc, SourceLocation RParenLoc); diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index eea475f869..e69a213247 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -641,15 +641,8 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, : CastExpr; ParsedType CastTy; SourceLocation RParenLoc; - - { - // The inside of the parens don't need to be a colon protected scope, and - // isn't immediately a message send. - ColonProtectionRAIIObject X(*this, false); - - Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/, - isTypeCast == IsTypeCast, CastTy, RParenLoc); - } + Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/, + isTypeCast == IsTypeCast, CastTy, RParenLoc); switch (ParenExprType) { case SimpleExpr: break; // Nothing else to do. @@ -1928,6 +1921,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, bool isTypeCast, ParsedType &CastTy, SourceLocation &RParenLoc) { assert(Tok.is(tok::l_paren) && "Not a paren expr!"); + ColonProtectionRAIIObject ColonProtection(*this, false); BalancedDelimiterTracker T(*this, tok::l_paren); if (T.consumeOpen()) return ExprError(); @@ -2003,6 +1997,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, TypeResult Ty = ParseTypeName(); T.consumeClose(); + ColonProtection.restore(); RParenLoc = T.getCloseLocation(); ExprResult SubExpr = ParseCastExpression(/*isUnaryExpression=*/false); @@ -2023,7 +2018,8 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, // if stopIfCastExpr is false, we need to determine the context past the // parens, so we defer to ParseCXXAmbiguousParenExpression for that. if (isAmbiguousTypeId && !stopIfCastExpr) { - ExprResult res = ParseCXXAmbiguousParenExpression(ExprType, CastTy, T); + ExprResult res = ParseCXXAmbiguousParenExpression(ExprType, CastTy, T, + ColonProtection); RParenLoc = T.getCloseLocation(); return res; } @@ -2051,6 +2047,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, } else { // Match the ')'. T.consumeClose(); + ColonProtection.restore(); RParenLoc = T.getCloseLocation(); if (Tok.is(tok::l_brace)) { ExprType = CompoundLiteral; diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index 7d9fa1482d..f1d6c8d642 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -2909,7 +2909,8 @@ ExprResult Parser::ParseExpressionTrait() { ExprResult Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, ParsedType &CastTy, - BalancedDelimiterTracker &Tracker) { + BalancedDelimiterTracker &Tracker, + ColonProtectionRAIIObject &ColonProt) { assert(getLangOpts().CPlusPlus && "Should only be called for C++!"); assert(ExprType == CastExpr && "Compound literals are not ambiguous!"); assert(isTypeIdInParens() && "Not a type-id!"); @@ -2958,6 +2959,7 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, // Try parsing the cast-expression that may follow. // If it is not a cast-expression, NotCastExpr will be true and no token // will be consumed. + ColonProt.restore(); Result = ParseCastExpression(false/*isUnaryExpression*/, false/*isAddressofOperand*/, NotCastExpr, @@ -2983,17 +2985,22 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, if (ParseAs >= CompoundLiteral) { // Parse the type declarator. DeclSpec DS(AttrFactory); - ParseSpecifierQualifierList(DS); Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); - ParseDeclarator(DeclaratorInfo); + { + ColonProtectionRAIIObject InnerColonProtection(*this); + ParseSpecifierQualifierList(DS); + ParseDeclarator(DeclaratorInfo); + } // Match the ')'. Tracker.consumeClose(); + ColonProt.restore(); if (ParseAs == CompoundLiteral) { ExprType = CompoundLiteral; + // FIXME: This is entirely wrong. TypeResult Ty = ParseTypeName(); - return ParseCompoundLiteralExpression(Ty.get(), + return ParseCompoundLiteralExpression(Ty.get(), Tracker.getOpenLocation(), Tracker.getCloseLocation()); } diff --git a/test/Parser/cxx-casting.cpp b/test/Parser/cxx-casting.cpp index 69680e421b..55309a1356 100644 --- a/test/Parser/cxx-casting.cpp +++ b/test/Parser/cxx-casting.cpp @@ -90,5 +90,16 @@ void test3() { // expected-error {{expected unqualified-id}} } +// Ensure that a C-style cast doesn't turn off colon protection. +void PR19748() { + struct A {}; + int A = 0, b; + int test1 = true ? (int)A : b; + + struct f {}; + extern B f(), (*p)(); + (true ? (B(*)())f : p)(); +} + // PR13619. Must be at end of file. int n = reinterpret_cast // expected-error {{expected '<'}} expected-error {{expected ';'}} |