lichray updated this revision to Diff 387017.
lichray added a comment.

- Manually adjust auto{x} formatting


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D113393/new/

https://reviews.llvm.org/D113393

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Parse/ParseExprCXX.cpp
  clang/lib/Parse/ParseTentative.cpp
  clang/lib/Sema/SemaExprCXX.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
  clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.auto.deduct/p2.cpp
  clang/test/CXX/expr/expr.post/expr.type.conv/p1-2b.cpp
  clang/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
  clang/test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp
  clang/test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp
  clang/test/Parser/cxx2b-auto-x.cpp
  clang/test/SemaCXX/deduced-return-type-cxx14.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===================================================================
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -1379,6 +1379,11 @@
       <td><a href="https://wg21.link/P2360R0";>P2360R0</a></td>
       <td class="unreleased" align="center">Clang 14</td>
     </tr>
+    <tr>
+      <td>auto(x): decay-copy in the language</td>
+      <td><a href="https://wg21.link/P0849R8";>P0849R8</a></td>
+      <td class="unreleased" align="center">Clang 14</td>
+    </tr>
 
 </table>
 </details>
Index: clang/test/SemaCXX/deduced-return-type-cxx14.cpp
===================================================================
--- clang/test/SemaCXX/deduced-return-type-cxx14.cpp
+++ clang/test/SemaCXX/deduced-return-type-cxx14.cpp
@@ -638,5 +638,7 @@
   using B = auto (*)() -> auto; // expected-error {{'auto' not allowed in type alias}}
   template<auto (*)() -> auto> struct X {}; // cxx14-error {{'auto' not allowed in template parameter until C++17}}
   template<typename T> struct Y { T x; };
-  Y<auto() -> auto> y; // expected-error {{'auto' not allowed in template argument}}
+  Y<auto() -> auto> y; // cxx14_20-error {{'auto' not allowed in template argument}} \
+                          cxx2b-error {{initializer for functional-style cast to 'auto' is empty}} \
+                          cxx2b-error {{expected unqualified-id}}
 }
Index: clang/test/Parser/cxx2b-auto-x.cpp
===================================================================
--- /dev/null
+++ clang/test/Parser/cxx2b-auto-x.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx2b -std=c++2b %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx20 -std=c++20 %s
+
+void looks_like_decltype_auto() {
+  decltype(auto(42)) b = 42; // cxx20-error {{'auto' not allowed here}}
+  decltype(long *) a = 42;   // expected-error {{expected '(' for function-style cast or type construction}} \
+                                expected-error {{expected expression}}
+  decltype(auto *) a = 42;   // expected-error {{expected '(' for function-style cast or type construction}} \
+                                expected-error {{expected expression}}
+  decltype(auto()) c = 42;   // cxx2b-error {{initializer for functional-style cast to 'auto' is empty}} \
+                                cxx20-error {{'auto' not allowed here}}
+}
+
+struct looks_like_declaration {
+  int n;
+} a;
+
+using T = looks_like_declaration *;
+void f() { T(&a)->n = 1; }
+void g() { auto(&a)->n = 0; } // cxx20-error {{declaration of variable 'a' with deduced type 'auto (&)' requires an initializer}} \
+                                 cxx20-error {{expected ';' at end of declaration}}
+void h() { auto{&a}->n = 0; } // cxx20-error {{expected unqualified-id}} \
+                                 cxx20-error {{expected expression}}
Index: clang/test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp
===================================================================
--- clang/test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp
+++ clang/test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp
@@ -1,11 +1,30 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14
 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++17 -pedantic
 
+// [expr.new]p2 ... the invented declaration: T x init ;
+// C++2b [dcl.type.auto.deduct]p2.2
+// For a variable declared with a type that contains a placeholder type, T is the declared type of the variable.
 void f() {
+  // - If the initializer is a parenthesized expression-list, the expression-list shall be a single assignmentexpression and E is the assignment-expression.
   new auto('a');
-  new auto {2};
-  new auto {1, 2}; // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
-  new auto {}; // expected-error{{new expression for type 'auto' requires a constructor argument}}
-  new decltype(auto)({1});
-  new decltype(auto)({1, 2}); // expected-error{{new expression for type 'decltype(auto)' contains multiple constructor arguments}}
+  new decltype(auto)('a');
+  // - If the initializer is a braced-init-list, it shall consist of a single brace-enclosed assignment-expression and E is the assignment-expression.
+  new auto{2};
+  new decltype(auto){2};
+
+  new auto{};   // expected-error{{new expression for type 'auto' requires a constructor argument}}
+  new auto({}); // expected-error{{cannot deduce actual type for 'auto' from parenthesized initializer list}}
+  new auto{{}}; // expected-error{{cannot deduce actual type for 'auto' from nested initializer list}}
+
+  new auto({2});  // expected-error{{cannot deduce actual type for 'auto' from parenthesized initializer list}}
+  new auto{{2}};  // expected-error{{cannot deduce actual type for 'auto' from nested initializer list}}
+  new auto{1, 2}; // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
+
+  new decltype(auto){};   // expected-error{{new expression for type 'decltype(auto)' requires a constructor argument}}
+  new decltype(auto)({}); // expected-error{{cannot deduce actual type for 'decltype(auto)' from parenthesized initializer list}}
+  new decltype(auto){{}}; // expected-error{{cannot deduce actual type for 'decltype(auto)' from nested initializer list}}
+
+  new decltype(auto)({1});    // expected-error{{cannot deduce actual type for 'decltype(auto)' from parenthesized initializer list}}
+  new decltype(auto){1, 2};   // expected-error{{new expression for type 'decltype(auto)' contains multiple constructor arguments}}
+  new decltype(auto)({1, 2}); // expected-error{{cannot deduce actual type for 'decltype(auto)' from parenthesized initializer list}}
 }
Index: clang/test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp
===================================================================
--- clang/test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp
+++ clang/test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp
@@ -5,6 +5,6 @@
   new auto {2}; // expected-warning {{ISO C++ standards before C++17 do not allow new expression for type 'auto' to use list-initialization}}
   new auto {1, 2}; // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
   new auto {}; // expected-error{{new expression for type 'auto' requires a constructor argument}}
-  new decltype(auto)({1}); // expected-warning {{ISO C++ standards before C++17 do not allow new expression for type 'decltype(auto)' to use list-initialization}}
-  new decltype(auto)({1, 2}); // expected-error{{new expression for type 'decltype(auto)' contains multiple constructor arguments}}
+  new decltype(auto)({1}); // expected-error{{cannot deduce actual type for 'decltype(auto)' from parenthesized initializer list}}
+  new decltype(auto)({1, 2}); // expected-error{{cannot deduce actual type for 'decltype(auto)' from parenthesized initializer list}}
 }
Index: clang/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
===================================================================
--- clang/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
+++ clang/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
@@ -16,7 +16,7 @@
   new (auto) (1,2,3); // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
   new auto {}; // expected-error{{new expression for type 'auto' requires a constructor argument}}
   new auto {1,2,3}; // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
-  new auto ({1,2,3}); // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
+  new auto ({1,2,3}); // expected-error{{cannot deduce actual type for 'auto' from parenthesized initializer list}}
 }
 
 void p2example() {
Index: clang/test/CXX/expr/expr.post/expr.type.conv/p1-2b.cpp
===================================================================
--- /dev/null
+++ clang/test/CXX/expr/expr.post/expr.type.conv/p1-2b.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -std=c++2b -verify %s
+
+template <class T>
+void foo(T);
+
+struct A {
+  int m;
+  char g(int);
+  float g(double);
+} a{1};
+
+// C++2b [dcl.type.auto.deduct]p2.3
+// For an explicit type conversion, T is the specified type, which shall be auto.
+void diagnostics() {
+  foo(auto());   // expected-error {{initializer for functional-style cast to 'auto' is empty}}
+  foo(auto{});   // expected-error {{initializer for functional-style cast to 'auto' is empty}}
+  foo(auto({})); // expected-error {{cannot deduce actual type for 'auto' from parenthesized initializer list}}
+  foo(auto{{}}); // expected-error {{cannot deduce actual type for 'auto' from nested initializer list}}
+
+  // - If the initializer is a parenthesized expression-list, the expression-list shall be a single assignmentexpression and E is the assignment-expression.
+  foo(auto(a));
+  // - If the initializer is a braced-init-list, it shall consist of a single brace-enclosed assignment-expression and E is the assignment-expression.
+  foo(auto{a});
+  foo(auto({a})); // expected-error {{cannot deduce actual type for 'auto' from parenthesized initializer list}}
+  foo(auto{{a}}); // expected-error {{cannot deduce actual type for 'auto' from nested initializer list}}
+
+  foo(auto(&A::g)); // expected-error {{functional-style cast to 'auto' has incompatible initializer of type '<overloaded function type>'}}
+
+  foo(auto(a, 3.14));     // expected-error {{initializer for functional-style cast to 'auto' contains multiple expressions}}
+  foo(auto{a, 3.14});     // expected-error {{initializer for functional-style cast to 'auto' contains multiple expressions}}
+  foo(auto({a, 3.14}));   // expected-error {{cannot deduce actual type for 'auto' from parenthesized initializer list}}
+  foo(auto{{a, 3.14}});   // expected-error {{cannot deduce actual type for 'auto' from nested initializer list}}
+  foo(auto({a}, {3.14})); // expected-error {{initializer for functional-style cast to 'auto' contains multiple expressions}}
+  foo(auto{{a}, {3.14}}); // expected-error {{initializer for functional-style cast to 'auto' contains multiple expressions}}
+
+  foo(auto{1, 2});   // expected-error {{initializer for functional-style cast to 'auto' contains multiple expressions}}
+  foo(auto({1, 2})); // expected-error {{cannot deduce actual type for 'auto' from parenthesized initializer list}}
+  foo(auto{{1, 2}}); // expected-error {{cannot deduce actual type for 'auto' from nested initializer list}}
+}
Index: clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.auto.deduct/p2.cpp
===================================================================
--- /dev/null
+++ clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.auto.deduct/p2.cpp
@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 -std=c++2b -verify %s
+
+void test_decay() {
+  int v[3];
+  static_assert(__is_same(decltype(auto(v)), int *));
+  static_assert(__is_same(decltype(auto{v}), int *));
+  static_assert(__is_same(decltype(auto("lit")), char const *));
+  static_assert(__is_same(decltype(auto{"lit"}), char const *));
+
+  int fn(char *);
+  static_assert(__is_same(decltype(auto(fn)), int (*)(char *)));
+  static_assert(__is_same(decltype(auto{fn}), int (*)(char *)));
+
+  constexpr long i = 1;
+  static_assert(__is_same(decltype(i), long const));
+  static_assert(__is_same(decltype(auto(1L)), long));
+  static_assert(__is_same(decltype(auto{1L}), long));
+  static_assert(__is_same(decltype(auto(i)), long));
+  static_assert(__is_same(decltype(auto{i}), long));
+
+  class A {
+  } a;
+
+  A &lr = a;
+  A const &lrc = a;
+  A &&rr = static_cast<A &&>(a);
+  A const &&rrc = static_cast<A &&>(a);
+
+  static_assert(__is_same(decltype(auto(lr)), A));
+  static_assert(__is_same(decltype(auto(lrc)), A));
+  static_assert(__is_same(decltype(auto(rr)), A));
+  static_assert(__is_same(decltype(auto(rrc)), A));
+}
+
+class cmdline_parser {
+public:
+  cmdline_parser(char const *);
+  auto add_option(char const *, char const *) && -> cmdline_parser &&;
+};
+
+void test_rvalue_fluent_interface() {
+  auto cmdline = cmdline_parser("driver");
+  auto internal = auto{cmdline}.add_option("--dump-full", "do not minimize dump");
+}
+
+template <class T> constexpr auto decay_copy(T &&v) { return static_cast<T &&>(v); } // expected-error {{calling a protected constructor of class 'A'}}
+
+class A {
+  int x;
+  friend void f(A &&);
+
+public:
+  A();
+
+  auto test_access() {
+    static_assert(__is_same(decltype(auto(*this)), A));
+    static_assert(__is_same(decltype(auto(this)), A *));
+
+    f(A(*this));          // ok
+    f(auto(*this));       // ok in P0849
+    f(decay_copy(*this)); // expected-note {{in instantiation of function template specialization 'decay_copy<A &>' requested here}}
+  }
+
+  auto test_access() const {
+    static_assert(__is_same(decltype(auto(*this)), A)); // ditto
+    static_assert(__is_same(decltype(auto(this)), A const *));
+  }
+
+protected:
+  A(const A &); // expected-note {{declared protected here}}
+};
+
+// post-C++17 semantics
+constexpr struct Uncopyable {
+  constexpr explicit Uncopyable(int) {}
+  constexpr Uncopyable(Uncopyable &&) = delete;
+} u = auto(Uncopyable(auto(Uncopyable(42))));
Index: clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
===================================================================
--- clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
+++ clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
@@ -51,8 +51,8 @@
   (void)reinterpret_cast<auto*>(&n); // expected-error{{'auto' not allowed here}}
   (void)const_cast<auto>(n); // expected-error{{'auto' not allowed here}}
   (void)*(auto*)(&n); // expected-error{{'auto' not allowed here}}
-  (void)auto(n); // expected-error{{expected expression}}
-  (void)auto{n}; // expected-error{{expected expression}}
+  (void)auto(n); // expected-error{{'auto' not allowed here}}
+  (void)auto{n}; // expected-error{{'auto' not allowed here}}
 }
 
 template <auto a = 10> class C { }; // expected-error{{'auto' not allowed in template parameter}}
Index: clang/lib/Sema/SemaType.cpp
===================================================================
--- clang/lib/Sema/SemaType.cpp
+++ clang/lib/Sema/SemaType.cpp
@@ -3395,6 +3395,7 @@
     // class template argument deduction)?
     bool IsCXXAutoType =
         (Auto && Auto->getKeyword() != AutoTypeKeyword::GNUAutoType);
+    bool IsAutoKeyword = (Auto && Auto->getKeyword() == AutoTypeKeyword::Auto);
     bool IsDeducedReturnType = false;
 
     switch (D.getContext()) {
@@ -3414,8 +3415,7 @@
       InventedTemplateParameterInfo *Info = nullptr;
       if (D.getContext() == DeclaratorContext::Prototype) {
         // With concepts we allow 'auto' in function parameters.
-        if (!SemaRef.getLangOpts().CPlusPlus20 || !Auto ||
-            Auto->getKeyword() != AutoTypeKeyword::Auto) {
+        if (!SemaRef.getLangOpts().CPlusPlus20 || !IsAutoKeyword) {
           Error = 0;
           break;
         } else if (!SemaRef.getCurScope()->isFunctionDeclarationScope()) {
@@ -3426,8 +3426,7 @@
         Info = &SemaRef.InventedParameterInfos.back();
       } else {
         // In C++14, generic lambdas allow 'auto' in their parameters.
-        if (!SemaRef.getLangOpts().CPlusPlus14 || !Auto ||
-            Auto->getKeyword() != AutoTypeKeyword::Auto) {
+        if (!SemaRef.getLangOpts().CPlusPlus14 || !IsAutoKeyword) {
           Error = 16;
           break;
         }
@@ -3505,6 +3504,8 @@
     case DeclaratorContext::FunctionalCast:
       if (isa<DeducedTemplateSpecializationType>(Deduced))
         break;
+      if (SemaRef.getLangOpts().CPlusPlus2b && IsAutoKeyword)
+        break; // auto(x)
       LLVM_FALLTHROUGH;
     case DeclaratorContext::TypeName:
       Error = 15; // Generic
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -1467,6 +1467,9 @@
   // C++1z [expr.type.conv]p1:
   //   If the type is a placeholder for a deduced class type, [...perform class
   //   template argument deduction...]
+  // C++2b:
+  //   Otherwise, if the type contains a placeholder type, it is replaced by the
+  //   type determined by placeholder type deduction.
   DeducedType *Deduced = Ty->getContainedDeducedType();
   if (Deduced && isa<DeducedTemplateSpecializationType>(Deduced)) {
     Ty = DeduceTemplateSpecializationFromInitializer(TInfo, Entity,
@@ -1474,6 +1477,36 @@
     if (Ty.isNull())
       return ExprError();
     Entity = InitializedEntity::InitializeTemporary(TInfo, Ty);
+  } else if (Deduced) {
+    MultiExprArg Inits = Exprs;
+    if (ListInitialization) {
+      auto *ILE = cast<InitListExpr>(Exprs[0]);
+      Inits = MultiExprArg(ILE->getInits(), ILE->getNumInits());
+    }
+
+    if (Inits.empty())
+      return ExprError(Diag(TyBeginLoc, diag::err_auto_expr_init_no_expression)
+                       << Ty << FullRange);
+    if (Inits.size() > 1) {
+      Expr *FirstBad = Inits[1];
+      return ExprError(Diag(FirstBad->getBeginLoc(),
+                            diag::err_auto_expr_init_multiple_expressions)
+                       << Ty << FullRange);
+    }
+    Expr *Deduce = Inits[0];
+    if (isa<InitListExpr>(Deduce))
+      return ExprError(
+          Diag(Deduce->getBeginLoc(), diag::err_auto_expr_init_paren_braces)
+          << ListInitialization << Ty << FullRange);
+    QualType DeducedType;
+    if (DeduceAutoType(TInfo, Deduce, DeducedType) == DAR_Failed)
+      return ExprError(Diag(TyBeginLoc, diag::err_auto_expr_deduction_failure)
+                       << Ty << Deduce->getType() << FullRange
+                       << Deduce->getSourceRange());
+    if (DeducedType.isNull())
+      return ExprError();
+    Ty = DeducedType;
+    Entity = InitializedEntity::InitializeTemporary(TInfo, Ty);
   }
 
   if (Ty->isDependentType() || CallExpr::hasAnyTypeDependentArguments(Exprs)) {
@@ -1980,12 +2013,10 @@
       return ExprError();
   } else if (Deduced) {
     bool Braced = (initStyle == CXXNewExpr::ListInit);
-    if (NumInits == 1) {
-      if (auto p = dyn_cast_or_null<InitListExpr>(Inits[0])) {
-        Inits = p->getInits();
-        NumInits = p->getNumInits();
-        Braced = true;
-      }
+    if (Braced) {
+      auto *ILE = cast<InitListExpr>(Inits[0]);
+      Inits = ILE->getInits();
+      NumInits = ILE->getNumInits();
     }
 
     if (initStyle == CXXNewExpr::NoInit || NumInits == 0)
@@ -2001,6 +2032,10 @@
       Diag(Initializer->getBeginLoc(), diag::ext_auto_new_list_init)
           << AllocType << TypeRange;
     Expr *Deduce = Inits[0];
+    if (isa<InitListExpr>(Deduce))
+      return ExprError(
+          Diag(Deduce->getBeginLoc(), diag::err_auto_expr_init_paren_braces)
+          << Braced << AllocType << TypeRange);
     QualType DeducedType;
     if (DeduceAutoType(AllocTypeInfo, Deduce, DeducedType) == DAR_Failed)
       return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure)
Index: clang/lib/Parse/ParseTentative.cpp
===================================================================
--- clang/lib/Parse/ParseTentative.cpp
+++ clang/lib/Parse/ParseTentative.cpp
@@ -1361,7 +1361,6 @@
   case tok::kw_static:
   case tok::kw_extern:
   case tok::kw_mutable:
-  case tok::kw_auto:
   case tok::kw___thread:
   case tok::kw_thread_local:
   case tok::kw__Thread_local:
@@ -1659,6 +1658,14 @@
 
     return TPResult::True;
 
+  // auto(x) in C++2b
+  case tok::kw_auto:
+    if (getLangOpts().CPlusPlus2b &&
+        NextToken().isOneOf(tok::l_paren, tok::l_brace))
+      return TPResult::Ambiguous;
+
+    return TPResult::True;
+
   // GNU typeof support.
   case tok::kw_typeof: {
     if (NextToken().isNot(tok::l_paren))
Index: clang/lib/Parse/ParseExprCXX.cpp
===================================================================
--- clang/lib/Parse/ParseExprCXX.cpp
+++ clang/lib/Parse/ParseExprCXX.cpp
@@ -2226,6 +2226,9 @@
   case tok::kw_void:
     DS.SetTypeSpecType(DeclSpec::TST_void, Loc, PrevSpec, DiagID, Policy);
     break;
+  case tok::kw_auto:
+    DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec, DiagID, Policy);
+    break;
   case tok::kw_char:
     DS.SetTypeSpecType(DeclSpec::TST_char, Loc, PrevSpec, DiagID, Policy);
     break;
Index: clang/lib/Parse/ParseExpr.cpp
===================================================================
--- clang/lib/Parse/ParseExpr.cpp
+++ clang/lib/Parse/ParseExpr.cpp
@@ -1523,6 +1523,7 @@
   case tok::kw___float128:
   case tok::kw___ibm128:
   case tok::kw_void:
+  case tok::kw_auto:
   case tok::kw_typename:
   case tok::kw_typeof:
   case tok::kw___vector:
Index: clang/lib/Parse/ParseDeclCXX.cpp
===================================================================
--- clang/lib/Parse/ParseDeclCXX.cpp
+++ clang/lib/Parse/ParseDeclCXX.cpp
@@ -1027,10 +1027,9 @@
     }
 
     // Check for C++1y 'decltype(auto)'.
-    if (Tok.is(tok::kw_auto)) {
-      // No need to disambiguate here: an expression can't start with 'auto',
-      // because the typename-specifier in a function-style cast operation can't
-      // be 'auto'.
+    if (Tok.is(tok::kw_auto) && NextToken().is(tok::r_paren)) {
+      // the typename-specifier in a function-style cast expression may
+      // be 'auto' since C++2b
       Diag(Tok.getLocation(),
            getLangOpts().CPlusPlus14
              ? diag::warn_cxx11_compat_decltype_auto_type_specifier
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2324,13 +2324,20 @@
   "type %0 to use list-initialization">, InGroup<CXX17>;
 def err_auto_var_init_no_expression : Error<
   "initializer for variable %0 with type %1 is empty">;
+def err_auto_expr_init_no_expression : Error<
+  "initializer for functional-style cast to %0 is empty">;
 def err_auto_var_init_multiple_expressions : Error<
   "initializer for variable %0 with type %1 contains multiple expressions">;
+def err_auto_expr_init_multiple_expressions : Error<
+  "initializer for functional-style cast to %0 contains multiple expressions">;
 def err_auto_var_init_paren_braces : Error<
   "cannot deduce type for variable %1 with type %2 from "
   "%select{parenthesized|nested}0 initializer list">;
 def err_auto_new_ctor_multiple_expressions : Error<
   "new expression for type %0 contains multiple constructor arguments">;
+def err_auto_expr_init_paren_braces : Error<
+  "cannot deduce actual type for %1 from "
+  "%select{parenthesized|nested}0 initializer list">;
 def err_auto_missing_trailing_return : Error<
   "'auto' return without trailing return type; deduced return types are a "
   "C++14 extension">;
@@ -2344,6 +2351,8 @@
   "variable %0 with type %1 has incompatible initializer of type %2">;
 def err_auto_var_deduction_failure_from_init_list : Error<
   "cannot deduce actual type for variable %0 with type %1 from initializer list">;
+def err_auto_expr_deduction_failure : Error<
+  "functional-style cast to %0 has incompatible initializer of type %1">;
 def err_auto_new_deduction_failure : Error<
   "new expression for type %0 has incompatible constructor argument of type %1">;
 def err_auto_inconsistent_deduction : Error<
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -153,6 +153,8 @@
 ^^^^^^^^^^^^^^^^^^^^^
 - Implemented `P1938R3: if consteval <https://wg21.link/P1938R3>`_.
 - Implemented `P2360R0: Extend init-statement to allow alias-declaration <https://wg21.link/P2360R0>`_.
+- Implemented `P0849R8: auto(x): decay-copy in the language
+ <https://wg21.link/P0849R8>`_.
 
 
 CUDA Language Changes in Clang
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to