]> granicus.if.org Git - clang/commitdiff
Improve diagonstic for braced-init-list as operand to ?: expression.
authorRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 24 May 2018 22:02:52 +0000 (22:02 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 24 May 2018 22:02:52 +0000 (22:02 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@333234 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Parse/ParseExpr.cpp
test/Parser/cxx11-brace-initializers.cpp

index 4fc2e34d44e563b036a881230ded4ae2fe7637f2..ec0af38c5bc01bd1fd7df9330f40aa9fab0141ea 100644 (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)
index 7926320fd021eaac0257fea14215cf490f456892..820344c578364cb2ca68e4f28f70d4ca36162ded 100644 (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 ':'}}