r320401 - P0620 follow-up: deducing `auto` from braced-init-list in new expr

Zhihao Yuan via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 11 10:29:55 PST 2017


Author: lichray
Date: Mon Dec 11 10:29:54 2017
New Revision: 320401

URL: http://llvm.org/viewvc/llvm-project?rev=320401&view=rev
Log:
P0620 follow-up: deducing `auto` from braced-init-list in new expr

Summary:
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

Reviewers: rsmith, aaron.ballman

Reviewed By: rsmith

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D39451

Added:
    cfe/trunk/test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp
    cfe/trunk/test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
    cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=320401&r1=320400&r2=320401&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Dec 11 10:29:54 2017
@@ -1988,8 +1988,9 @@ def err_auto_var_requires_init : Error<
   "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 ext_auto_new_list_init : Extension<
+  "ISO C++ standards before C++17 do not allow new expression for "
+  "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_var_init_multiple_expressions : Error<

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=320401&r1=320400&r2=320401&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Dec 11 10:29:54 2017
@@ -1748,20 +1748,27 @@ Sema::BuildCXXNew(SourceRange Range, boo
     if (AllocType.isNull())
       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 (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(),
                             diag::err_auto_new_ctor_multiple_expressions)
                        << AllocType << TypeRange);
     }
+    if (Braced && !getLangOpts().CPlusPlus17)
+      Diag(Initializer->getLocStart(), diag::ext_auto_new_list_init)
+          << AllocType << TypeRange;
     Expr *Deduce = Inits[0];
     QualType DeducedType;
     if (DeduceAutoType(AllocTypeInfo, Deduce, DeducedType) == DAR_Failed)

Modified: cfe/trunk/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp?rev=320401&r1=320400&r2=320401&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp Mon Dec 11 10:29:54 2017
@@ -9,12 +9,14 @@ struct only {
 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() {

Added: cfe/trunk/test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp?rev=320401&view=auto
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp (added)
+++ cfe/trunk/test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp Mon Dec 11 10:29:54 2017
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14 -pedantic
+
+void f() {
+  new auto('a');
+  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}}
+}

Added: cfe/trunk/test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp?rev=320401&view=auto
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp (added)
+++ cfe/trunk/test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp Mon Dec 11 10:29:54 2017
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++17 -pedantic
+
+void f() {
+  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}}
+}

Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp?rev=320401&r1=320400&r2=320401&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp Mon Dec 11 10:29:54 2017
@@ -148,7 +148,7 @@ void auto_deduction() {
 }
 
 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}}
 }
 




More information about the cfe-commits mailing list