summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhihao Yuan <zy@miator.net>2017-12-11 18:29:54 +0000
committerZhihao Yuan <zy@miator.net>2017-12-11 18:29:54 +0000
commit00c9dfdfd0941a52902d81a8e377b28037ee494d (patch)
tree1662153a646961bd8a07f06b45a953f3f5a9f95a
parent5512525c5d87b241adcca122fd315c073066eadb (diff)
downloadbcm5719-llvm-00c9dfdfd0941a52902d81a8e377b28037ee494d.tar.gz
bcm5719-llvm-00c9dfdfd0941a52902d81a8e377b28037ee494d.zip
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 llvm-svn: 320401
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td5
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp17
-rw-r--r--clang/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp6
-rw-r--r--clang/test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp10
-rw-r--r--clang/test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp11
-rw-r--r--clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp2
6 files changed, 41 insertions, 10 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index b5e1b09666a..14db7bf5569 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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<
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index cd0d7157415..9c842ded1e1 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1748,20 +1748,27 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
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)
diff --git a/clang/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp b/clang/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
index 7305bd1f53e..a3a2f712c80 100644
--- a/clang/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
+++ b/clang/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
@@ -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() {
diff --git a/clang/test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp b/clang/test/CXX/expr/expr.unary/expr.new/p2-cxx14.cpp
new file mode 100644
index 00000000000..70bbc4805c4
--- /dev/null
+++ b/clang/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}}
+}
diff --git a/clang/test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp b/clang/test/CXX/expr/expr.unary/expr.new/p2-cxx1z.cpp
new file mode 100644
index 00000000000..6e76075ab16
--- /dev/null
+++ b/clang/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}}
+}
diff --git a/clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp b/clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
index 78ebc048b26..860a4aa6c6f 100644
--- a/clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
+++ b/clang/test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
@@ -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}}
}
OpenPOWER on IntegriCloud