[cfe-commits] r151794 - in /cfe/trunk: include/clang/Basic/DiagnosticParseKinds.td lib/Parse/ParseExpr.cpp test/CXX/expr/expr.ass/p9-cxx11.cpp
Eli Friedman
eli.friedman at gmail.com
Wed Feb 29 19:24:42 PST 2012
On Wed, Feb 29, 2012 at 6:59 PM, Richard Smith
<richard-llvm at metafoo.co.uk> wrote:
> Author: rsmith
> Date: Wed Feb 29 20:59:17 2012
> New Revision: 151794
>
> URL: http://llvm.org/viewvc/llvm-project?rev=151794&view=rev
> Log:
> Reject 'a = {0} = {0}' rather than parsing it as '(a = {0}) = {0}'. Also
> improve the diagnostics for some attempts to use initializer lists in
> expressions.
>
> Modified:
> cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
> cfe/trunk/lib/Parse/ParseExpr.cpp
> cfe/trunk/test/CXX/expr/expr.ass/p9-cxx11.cpp
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=151794&r1=151793&r2=151794&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Wed Feb 29 20:59:17 2012
> @@ -229,6 +229,8 @@
> def warn_cxx98_compat_generalized_initializer_lists : Warning<
> "generalized initializer lists are incompatible with C++98">,
> InGroup<CXX98Compat>, DefaultIgnore;
> +def err_init_list_bin_op : Error<"initializer list cannot be used on the "
> + "%select{left|right}0 hand side of operator '%1'">;
> def warn_cxx98_compat_trailing_return_type : Warning<
> "trailing return types are incompatible with C++98">,
> InGroup<CXX98Compat>, DefaultIgnore;
>
> Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=151794&r1=151793&r2=151794&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseExpr.cpp Wed Feb 29 20:59:17 2012
> @@ -282,6 +282,12 @@
> Token OpToken = Tok;
> ConsumeToken();
>
> + if (!LHS.isInvalid() && isa<InitListExpr>(LHS.get())) {
> + Diag(OpToken, diag::err_init_list_bin_op)
> + << /*LHS*/0 << PP.getSpelling(OpToken) << LHS.get()->getSourceRange();
> + LHS = ExprError();
> + }
> +
> // Special case handling for the ternary operator.
> ExprResult TernaryMiddle(true);
> if (NextTokPrec == prec::Conditional) {
> @@ -353,22 +359,16 @@
> // Therefore we need some special-casing here.
> // Also note that the third operand of the conditional operator is
> // an assignment-expression in C++, and in C++11, we can have a
> - // braced-init-list on the RHS of an assignment.
> + // braced-init-list on the RHS of an assignment. For better diagnostics,
> + // parse as if we were allowed braced-init-lists everywhere, and check that
> + // they only appear on the RHS of assignments later.
> ExprResult RHS;
> - if (getLang().CPlusPlus0x && MinPrec == prec::Assignment &&
> - Tok.is(tok::l_brace)) {
> - Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists);
> + if (getLang().CPlusPlus0x && Tok.is(tok::l_brace))
> RHS = ParseBraceInitializer();
> - if (LHS.isInvalid() || RHS.isInvalid())
> - return ExprError();
> - // A braced-init-list can never be followed by more operators.
> - return Actions.ActOnBinOp(getCurScope(), OpToken.getLocation(),
> - OpToken.getKind(), LHS.take(), RHS.take());
> - } else if (getLang().CPlusPlus && NextTokPrec <= prec::Conditional) {
> + else if (getLang().CPlusPlus && NextTokPrec <= prec::Conditional)
> RHS = ParseAssignmentExpression();
> - } else {
> + else
> RHS = ParseCastExpression(false);
> - }
>
> if (RHS.isInvalid())
> LHS = ExprError();
> @@ -387,6 +387,11 @@
> // more tightly with RHS than we do, evaluate it completely first.
> if (ThisPrec < NextTokPrec ||
> (ThisPrec == NextTokPrec && isRightAssoc)) {
> + if (!LHS.isInvalid() && isa<InitListExpr>(LHS.get())) {
> + Diag(OpToken, diag::err_init_list_bin_op)
> + << /*LHS*/0 << PP.getSpelling(OpToken) << LHS.get()->getSourceRange();
> + LHS = ExprError();
> + }
We normally try to avoid the Parser using AST methods directly...
granted, the distinction between Parser and Sema has started to blur a
bit, but I think it's still useful to try to maintain.
-Eli
More information about the cfe-commits
mailing list