Improve diagonstic for braced-init-list as operand to ?: expression.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@333234 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Richard Smith 2018-05-24 22:02:52 +00:00
parent 3211ce51c4
commit bfc08965af
2 changed files with 25 additions and 7 deletions

View File

@ -336,7 +336,17 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
// Special case handling for the ternary operator.
ExprResult TernaryMiddle(true);
if (NextTokPrec == prec::Conditional) {
if (Tok.isNot(tok::colon)) {
if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) {
// Parse a braced-init-list here for error recovery purposes.
SourceLocation BraceLoc = Tok.getLocation();
TernaryMiddle = ParseBraceInitializer();
if (!TernaryMiddle.isInvalid()) {
Diag(BraceLoc, diag::err_init_list_bin_op)
<< /*RHS*/ 1 << PP.getSpelling(OpToken)
<< Actions.getExprRange(TernaryMiddle.get());
TernaryMiddle = ExprError();
}
} else if (Tok.isNot(tok::colon)) {
// Don't parse FOO:BAR as if it were a typo for FOO::BAR.
ColonProtectionRAIIObject X(*this);
@ -345,11 +355,6 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
// In particular, the RHS of the '?' is 'expression', not
// 'logical-OR-expression' as we might expect.
TernaryMiddle = ParseExpression();
if (TernaryMiddle.isInvalid()) {
Actions.CorrectDelayedTyposInExpr(LHS);
LHS = ExprError();
TernaryMiddle = nullptr;
}
} else {
// Special case handling of "X ? Y : Z" where Y is empty:
// logical-OR-expression '?' ':' conditional-expression [GNU]
@ -357,6 +362,12 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
Diag(Tok, diag::ext_gnu_conditional_expr);
}
if (TernaryMiddle.isInvalid()) {
Actions.CorrectDelayedTyposInExpr(LHS);
LHS = ExprError();
TernaryMiddle = nullptr;
}
if (!TryConsumeToken(tok::colon, ColonLoc)) {
// Otherwise, we're missing a ':'. Assume that this was a typo that
// the user forgot. If we're not in a macro expansion, we can suggest
@ -469,6 +480,11 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
if (ThisPrec == prec::Assignment) {
Diag(OpToken, diag::warn_cxx98_compat_generalized_initializer_lists)
<< Actions.getExprRange(RHS.get());
} else if (ColonLoc.isValid()) {
Diag(ColonLoc, diag::err_init_list_bin_op)
<< /*RHS*/1 << ":"
<< Actions.getExprRange(RHS.get());
LHS = ExprError();
} else {
Diag(OpToken, diag::err_init_list_bin_op)
<< /*RHS*/1 << PP.getSpelling(OpToken)

View File

@ -1,5 +1,4 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
// expected-no-diagnostics
struct S {
S(int, int) {}
@ -25,3 +24,6 @@ namespace PR14948 {
template<typename T> T Q<T>::x {};
}
int conditional1 = 1 ? {} : 0; // expected-error {{initializer list cannot be used on the right hand side of operator '?'}}
int conditional2 = 1 ? 0 : {}; // expected-error {{initializer list cannot be used on the right hand side of operator ':'}}