[PATCH] D39451: P0620 follow-up: deducing `auto` from braced-init-list in new expr

Zhihao Yuan via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 31 00:16:30 PDT 2017


lichray created this revision.

This is a side-effect brought in by p0620r0, which allows other placeholder types (derived from `auto` and `decltype(auto)`) to be usable in a `new` expression with a single-clause //braced-init-list// as its initializer (8.3.4 [expr.new]/2).  N3922 defined its semantics.

References:
 http://wg21.link/p0620r0
 http://wg21.link/n3922


https://reviews.llvm.org/D39451

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaExprCXX.cpp
  test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
  test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp


Index: test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
===================================================================
--- test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -148,7 +148,7 @@
 }
 
 void dangle() {
-  new auto{1, 2, 3}; // expected-error {{cannot use list-initialization}}
+  new auto{1, 2, 3}; // expected-error {{new expression for type 'auto' contains multiple constructor arguments}}
   new std::initializer_list<int>{1, 2, 3}; // expected-warning {{at the end of the full-expression}}
 }
 
Index: test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
===================================================================
--- test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
+++ test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
@@ -9,12 +9,14 @@
 void f() {
   only<const int*> p = new const auto (0);
   only<double*> q = new (auto) (0.0);
+  only<char*> r = new auto {'a'};
 
   new auto; // expected-error{{new expression for type 'auto' requires a constructor argument}}
   new (const auto)(); // expected-error{{new expression for type 'const 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' cannot use list-initialization}}
-  new auto ({1,2,3}); // expected-error{{new expression for type 'auto' cannot use list-initialization}}
+  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}}
 }
 
 void p2example() {
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -1748,14 +1748,16 @@
     if (AllocType.isNull())
       return ExprError();
   } else if (Deduced) {
+    if (NumInits == 1) {
+      if (auto p = dyn_cast_or_null<InitListExpr>(Inits[0])) {
+        Inits = p->getInits();
+        NumInits = p->getNumInits();
+      }
+    }
+
     if (initStyle == CXXNewExpr::NoInit || NumInits == 0)
       return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg)
                        << AllocType << TypeRange);
-    if (initStyle == CXXNewExpr::ListInit ||
-        (NumInits == 1 && isa<InitListExpr>(Inits[0])))
-      return ExprError(Diag(Inits[0]->getLocStart(),
-                            diag::err_auto_new_list_init)
-                       << AllocType << TypeRange);
     if (NumInits > 1) {
       Expr *FirstBad = Inits[1];
       return ExprError(Diag(FirstBad->getLocStart(),
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -1981,8 +1981,6 @@
   "declaration of variable %0 with deduced type %1 requires an initializer">;
 def err_auto_new_requires_ctor_arg : Error<
   "new expression for type %0 requires a constructor argument">;
-def err_auto_new_list_init : Error<
-  "new expression for type %0 cannot use list-initialization">;
 def err_auto_var_init_no_expression : Error<
   "initializer for variable %0 with type %1 is empty">;
 def err_auto_var_init_multiple_expressions : Error<


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D39451.120938.patch
Type: text/x-patch
Size: 3538 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20171031/763bd870/attachment.bin>


More information about the cfe-commits mailing list