[PATCH] D39451: P0620 follow-up: deducing `auto` from braced-init-list in new expr
This revision was automatically updated to reflect the committed changes. Closed by commit rC320401: P0620 follow-up: deducing `auto` from braced-init-list in new expr (authored by lichray). Changed prior to commit: https://reviews.llvm.org/D39451?vs=126092=126400#toc Repository: rC Clang 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/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp test/CXX/expr/expr.unary/expr.new/p2-cxx1z.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{1, 2, 3}; // expected-warning {{at the end of the full-expression}} } Index: test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp === --- test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp +++ test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp @@ -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}} +} Index: test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp === --- test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp +++ test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp @@ -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}} +} 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 p = new const auto (0); onlyq = new (auto) (0.0); + only 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,20 +1748,27 @@ if (AllocType.isNull()) return ExprError(); } else if (Deduced) { +bool Braced = (initStyle == CXXNewExpr::ListInit); +if (NumInits == 1) { + if (auto p = dyn_cast_or_null(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 &&
[PATCH] D39451: P0620 follow-up: deducing `auto` from braced-init-list in new expr
rsmith accepted this revision. rsmith added inline comments. This revision is now accepted and ready to land. Comment at: include/clang/Basic/DiagnosticSemaKinds.td:1992 +def ext_auto_new_list_init : Extension< + "ISO C++ standards before C++17 does not allow new expression for " + "type %0 using list-initialization">, InGroup; does not -> do not, using -> to use Comment at: lib/Sema/SemaExprCXX.cpp:1763-1765 +if (Braced && !getLangOpts().CPlusPlus17) + Diag(Initializer->getLocStart(), diag::ext_auto_new_list_init) + << AllocType << TypeRange; Move this after the "ctor_multiple_expressions" diagnostic below. Repository: rC Clang https://reviews.llvm.org/D39451 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39451: P0620 follow-up: deducing `auto` from braced-init-list in new expr
lichray added a comment. Ping? Repository: rC Clang https://reviews.llvm.org/D39451 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39451: P0620 follow-up: deducing `auto` from braced-init-list in new expr
lichray updated this revision to Diff 126092. lichray added a comment. Keep a pedantic Extension warning. Repository: rC Clang 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/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp test/CXX/expr/expr.unary/expr.new/p2-cxx1z.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{1, 2, 3}; // expected-warning {{at the end of the full-expression}} } Index: test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp === --- /dev/null +++ test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp @@ -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({1}); + new auto {}; // expected-error{{new expression for type 'auto' requires a constructor argument}} + new decltype(auto)({1, 2}); // expected-error{{new expression for type 'decltype(auto)' contains multiple constructor arguments}} +} Index: test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp === --- /dev/null +++ test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp @@ -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 does not allow new expression for type 'auto' using list-initialization}} + new auto {1, 2}; // expected-warning {{ISO C++ standards before C++17 does not allow new expression for type 'auto' using list-initialization}} expected-error{{new expression for type 'auto' contains multiple constructor arguments}} + new auto({1}); // expected-warning {{ISO C++ standards before C++17 does not allow new expression for type 'auto' using list-initialization}} + new auto {}; // expected-error{{new expression for type 'auto' requires a constructor argument}} + new decltype(auto)({1, 2}); // expected-warning {{ISO C++ standards before C++17 does not allow new expression for type 'decltype(auto)' using list-initialization}} expected-error{{new expression for type 'decltype(auto)' contains multiple constructor arguments}} +} 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 p = new const auto (0); onlyq = new (auto) (0.0); + only 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,21 @@ if (AllocType.isNull()) return ExprError(); } else if (Deduced) { +bool Braced = (initStyle == CXXNewExpr::ListInit); +if (NumInits == 1) { + if (auto p = dyn_cast_or_null(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 &&
[PATCH] D39451: P0620 follow-up: deducing `auto` from braced-init-list in new expr
rsmith added a comment. EDG and MSVC do not appear to treat this as a defect resolution; I suspect this is an oversight in GCC rather than an intentional extension. Let's convert the error to an (off by default) pedantic `Extension` (ISO C++11 does not allow ...), and suppress the extension warning in C++17 onwards. https://reviews.llvm.org/D39451 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39451: P0620 follow-up: deducing `auto` from braced-init-list in new expr
lichray added a comment. Ping. Just accept this as a DR, like what GCC does, I guess? https://reviews.llvm.org/D39451 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D39451: P0620 follow-up: deducing `auto` from braced-init-list in new expr
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{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 p = new const auto (0); onlyq = new (auto) (0.0); + only 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(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(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< 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{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 p = new const auto (0); only q = new (auto)