From: Chris Lattner Date: Thu, 10 Dec 2009 02:08:07 +0000 (+0000) Subject: If we enter parens, colons can become un-sacred, allowing us to emit X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=932dff777d58a23e3a26967a61bb52697c542fd4;p=clang If we enter parens, colons can become un-sacred, allowing us to emit a better diagnostic in the second example. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91040 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 2536cee1cb..bdbc67f782 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -565,9 +565,15 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, TypeTy *CastTy; SourceLocation LParenLoc = Tok.getLocation(); SourceLocation RParenLoc; - Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/, - TypeOfCast, CastTy, RParenLoc); - if (Res.isInvalid()) return move(Res); + + { + // The inside of the parens don't need to be a colon protected scope. + ColonProtectionRAIIObject X(*this, false); + + Res = ParseParenExpression(ParenExprType, false/*stopIfCastExr*/, + TypeOfCast, CastTy, RParenLoc); + if (Res.isInvalid()) return move(Res); + } switch (ParenExprType) { case SimpleExpr: break; // Nothing else to do. diff --git a/lib/Parse/RAIIObjectsForParser.h b/lib/Parse/RAIIObjectsForParser.h index 93b9a82fdc..d048f04341 100644 --- a/lib/Parse/RAIIObjectsForParser.h +++ b/lib/Parse/RAIIObjectsForParser.h @@ -48,8 +48,9 @@ namespace clang { Parser &P; bool OldVal; public: - ColonProtectionRAIIObject(Parser &p) : P(p), OldVal(P.ColonIsSacred) { - P.ColonIsSacred = true; + ColonProtectionRAIIObject(Parser &p, bool Value = true) + : P(p), OldVal(P.ColonIsSacred) { + P.ColonIsSacred = Value; } /// restore - This can be used to restore the state early, before the dtor diff --git a/test/Parser/cxx-decl.cpp b/test/Parser/cxx-decl.cpp index 38467117b3..6f3fd391b9 100644 --- a/test/Parser/cxx-decl.cpp +++ b/test/Parser/cxx-decl.cpp @@ -9,7 +9,8 @@ struct Type { // PR4451 - We should recover well from the typo of '::' as ':' in a2. namespace y { - struct a { }; + struct a { }; + typedef int b; } y::a a1; @@ -45,4 +46,9 @@ struct a { void test(struct Type *P) { int Type; Type = 1 ? P->Type : Type; + + Type = (y:b) 4; // expected-error {{unexpected ':' in nested name specifier}} + Type = 1 ? ( + (y:b) // expected-error {{unexpected ':' in nested name specifier}} + 4) : 5; } \ No newline at end of file