aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2009-06-02 13:02:38 -0400
committerJason Merrill <jason@gcc.gnu.org>2009-06-02 13:02:38 -0400
commit4ea08463a743ae12a5273368c2cc50743818ad48 (patch)
treea4bc703b59430cc1c6271ad1407d17d48be44c0d /gcc
parentccafc19b5bd8f4736a2788263aa5acd6d2b7a961 (diff)
downloadgcc-4ea08463a743ae12a5273368c2cc50743818ad48.zip
gcc-4ea08463a743ae12a5273368c2cc50743818ad48.tar.gz
gcc-4ea08463a743ae12a5273368c2cc50743818ad48.tar.bz2
re PR c++/40308 (Brace initialization fails for member initializers in constructor for class templates)
PR c++/40308 PR c++/40311 * typeck.c (cp_build_modify_expr): Always pass init-lists to the conversion code. * call.c (implicit_conversion): Allow init-list conversion to scalar during direct-initialization, too. Mark the conversion bad if it has too many levels of braces. (convert_like_real): And give a helpful error. From-SVN: r148089
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog11
-rw-r--r--gcc/cp/call.c26
-rw-r--r--gcc/cp/typeck.c5
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist13.C5
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist18.C19
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/initlist19.C8
7 files changed, 69 insertions, 9 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 448b558..e3eb576 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,4 +1,13 @@
-2009-06-01 Jason Merrill <jason@redhat.com>
+2009-06-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/40308
+ PR c++/40311
+ * typeck.c (cp_build_modify_expr): Always pass init-lists to the
+ conversion code.
+ * call.c (implicit_conversion): Allow init-list conversion to scalar
+ during direct-initialization, too. Mark the conversion bad if it
+ has too many levels of braces.
+ (convert_like_real): And give a helpful error.
PR c++/40306
PR c++/40307
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 138abe0..1ab27c7 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1406,21 +1406,27 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
return build_list_conv (to, expr, flags);
/* Allow conversion from an initializer-list with one element to a
- scalar type if this is copy-initialization. Direct-initialization
- would be something like int i({1}), which is invalid. */
- if (SCALAR_TYPE_P (to) && CONSTRUCTOR_NELTS (expr) <= 1
- && (flags & LOOKUP_ONLYCONVERTING))
+ scalar type. */
+ if (SCALAR_TYPE_P (to))
{
+ int nelts = CONSTRUCTOR_NELTS (expr);
tree elt;
- if (CONSTRUCTOR_NELTS (expr) == 1)
+
+ if (nelts == 0)
+ elt = integer_zero_node;
+ else if (nelts == 1)
elt = CONSTRUCTOR_ELT (expr, 0)->value;
else
- elt = integer_zero_node;
+ elt = error_mark_node;
+
conv = implicit_conversion (to, TREE_TYPE (elt), elt,
c_cast_p, flags);
if (conv)
{
conv->check_narrowing = true;
+ if (BRACE_ENCLOSED_INITIALIZER_P (elt))
+ /* Too many levels of braces, i.e. '{{1}}'. */
+ conv->bad_p = true;
return conv;
}
}
@@ -4698,6 +4704,14 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
&& convs->kind != ck_base)
{
conversion *t = convs;
+
+ /* Give a helpful error if this is bad because of excess braces. */
+ if (BRACE_ENCLOSED_INITIALIZER_P (expr)
+ && SCALAR_TYPE_P (totype)
+ && CONSTRUCTOR_NELTS (expr) > 0
+ && BRACE_ENCLOSED_INITIALIZER_P (CONSTRUCTOR_ELT (expr, 0)->value))
+ permerror (input_location, "too many braces around initializer for %qT", totype);
+
for (; t; t = convs->u.next)
{
if (t->kind == ck_user || !t->bad_p)
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 6f6bd39..b384fea 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -6081,8 +6081,11 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
if (modifycode == INIT_EXPR)
{
- if (TREE_CODE (rhs) == CONSTRUCTOR)
+ if (BRACE_ENCLOSED_INITIALIZER_P (rhs))
+ /* Do the default thing. */;
+ else if (TREE_CODE (rhs) == CONSTRUCTOR)
{
+ /* Compound literal. */
if (! same_type_p (TREE_TYPE (rhs), lhstype))
/* Call convert to generate an error; see PR 11063. */
rhs = convert (lhstype, rhs);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9743b5d..fda5ce3 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2009-06-02 Jason Merrill <jason@redhat.com>
+ * g++.dg/cpp0x/initlist13.C: Remove expected error.
+ * g++.dg/cpp0x/initlist18.C: New.
+ * g++.dg/cpp0x/initlist19.C: New.
+
* g++.dg/cpp0x/auto14.C: New.
2009-06-02 Eric Botcazou <ebotcazou@adacore.com>
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist13.C b/gcc/testsuite/g++.dg/cpp0x/initlist13.C
index 98af92b..9ed6c74 100644
--- a/gcc/testsuite/g++.dg/cpp0x/initlist13.C
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist13.C
@@ -2,4 +2,7 @@
// { dg-do compile }
// { dg-options "-std=gnu++0x" }
-__complex__ int i ({0}); // { dg-error "cannot convert" }
+#include <complex>
+
+__complex__ int i ({0});
+std::complex<int> i2 ({0});
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist18.C b/gcc/testsuite/g++.dg/cpp0x/initlist18.C
new file mode 100644
index 0000000..c9a9bcd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist18.C
@@ -0,0 +1,19 @@
+// PR c++/40308, 40311
+// { dg-do run }
+// { dg-options "-std=c++0x" }
+
+template< typename T >
+struct test {
+ test() : data{} {}
+
+ T data;
+};
+
+int main()
+{
+ test<int> x;
+ test<int*> y;
+ int * a = new int{};
+ int * b = new int{5};
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist19.C b/gcc/testsuite/g++.dg/cpp0x/initlist19.C
new file mode 100644
index 0000000..418cddc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist19.C
@@ -0,0 +1,8 @@
+// { dg-options "-std=c++0x" }
+
+void f(double);
+int main()
+{
+ f({{1}}); // { dg-error "too many braces" }
+ // { dg-error "" "" { target *-*-* } 6 } allow other errors, too
+}