r208843 - PR19748: Make sure we don't lose colon protection after the parenthesized type-id in a cast-expression.
Richard Smith
richard-llvm at metafoo.co.uk
Wed May 14 19:43:47 PDT 2014
Author: rsmith
Date: Wed May 14 21:43:47 2014
New Revision: 208843
URL: http://llvm.org/viewvc/llvm-project?rev=208843&view=rev
Log:
PR19748: Make sure we don't lose colon protection after the parenthesized type-id in a cast-expression.
Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseExpr.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/test/Parser/cxx-casting.cpp
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=208843&r1=208842&r2=208843&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Wed May 14 21:43:47 2014
@@ -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);
Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=208843&r1=208842&r2=208843&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Wed May 14 21:43:47 2014
@@ -641,15 +641,8 @@ ExprResult Parser::ParseCastExpression(b
: 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(ParenParseO
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(ParenParseO
TypeResult Ty = ParseTypeName();
T.consumeClose();
+ ColonProtection.restore();
RParenLoc = T.getCloseLocation();
ExprResult SubExpr = ParseCastExpression(/*isUnaryExpression=*/false);
@@ -2023,7 +2018,8 @@ Parser::ParseParenExpression(ParenParseO
// 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(ParenParseO
} else {
// Match the ')'.
T.consumeClose();
+ ColonProtection.restore();
RParenLoc = T.getCloseLocation();
if (Tok.is(tok::l_brace)) {
ExprType = CompoundLiteral;
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=208843&r1=208842&r2=208843&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Wed May 14 21:43:47 2014
@@ -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
// 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
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());
}
Modified: cfe/trunk/test/Parser/cxx-casting.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-casting.cpp?rev=208843&r1=208842&r2=208843&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-casting.cpp (original)
+++ cfe/trunk/test/Parser/cxx-casting.cpp Wed May 14 21:43:47 2014
@@ -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 ';'}}
More information about the cfe-commits
mailing list