diff options
author | Jason Merrill <jason@redhat.com> | 2011-04-11 18:01:04 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2011-04-11 18:01:04 -0400 |
commit | 80c6dcf59bf7b192f107a2d950877a6b09fc6084 (patch) | |
tree | 3b58eebc8734149498c7501b9210b12e419ac019 /gcc | |
parent | 76186d20ccf5c5c34f5f4fe2e721738d28890a4a (diff) | |
download | gcc-80c6dcf59bf7b192f107a2d950877a6b09fc6084.zip gcc-80c6dcf59bf7b192f107a2d950877a6b09fc6084.tar.gz gcc-80c6dcf59bf7b192f107a2d950877a6b09fc6084.tar.bz2 |
re PR c++/48535 ([C++0x][SFINAE] Hard errors during list-value-initialization)
PR c++/48535
* decl.c (cp_complete_array_type_or_error): New.
* semantics.c (finish_compound_literal): Use it.
* cp-tree.h: Declare it.
From-SVN: r172287
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/decl.c | 33 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 2 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/sfinae12.C | 18 |
6 files changed, 67 insertions, 2 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d5975fc..bf7113f 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,6 +1,11 @@ 2011-04-11 Jason Merrill <jason@redhat.com> PR c++/48535 + * decl.c (cp_complete_array_type_or_error): New. + * semantics.c (finish_compound_literal): Use it. + * cp-tree.h: Declare it. + + PR c++/48535 * semantics.c (finish_compound_literal): Handle references. PR c++/48535 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 44a20ea..4321d28 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4791,6 +4791,7 @@ extern void start_decl_1 (tree, bool); extern bool check_array_initializer (tree, tree, tree); extern void cp_finish_decl (tree, tree, bool, tree, int); extern int cp_complete_array_type (tree *, tree, bool); +extern int cp_complete_array_type_or_error (tree *, tree, bool, tsubst_flags_t); extern tree build_ptrmemfunc_type (tree); extern tree build_ptrmem_type (tree, tree); /* the grokdeclarator prototype is in decl.h */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index a541402..7dea9b7 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -6689,6 +6689,39 @@ cp_complete_array_type (tree *ptype, tree initial_value, bool do_default) return failure; } + +/* As above, but either give an error or reject zero-size arrays, depending + on COMPLAIN. */ + +int +cp_complete_array_type_or_error (tree *ptype, tree initial_value, + bool do_default, tsubst_flags_t complain) +{ + int failure; + bool sfinae = !(complain & tf_error); + /* In SFINAE context we can't be lenient about zero-size arrays. */ + if (sfinae) + ++pedantic; + failure = cp_complete_array_type (ptype, initial_value, do_default); + if (sfinae) + --pedantic; + if (failure) + { + if (sfinae) + /* Not an error. */; + else if (failure == 1) + error ("initializer fails to determine size of %qT", *ptype); + else if (failure == 2) + { + if (do_default) + error ("array size missing in %qT", *ptype); + } + else if (failure == 3) + error ("zero-size array %qT", *ptype); + *ptype = error_mark_node; + } + return failure; +} /* Return zero if something is declared to be a member of type CTYPE when in the context of CUR_TYPE. STRING is the error diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 461aa0a..61d87be 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2355,8 +2355,14 @@ finish_compound_literal (tree type, tree compound_literal, && check_array_initializer (NULL_TREE, type, compound_literal)) return error_mark_node; compound_literal = reshape_init (type, compound_literal); - if (TREE_CODE (type) == ARRAY_TYPE) - cp_complete_array_type (&type, compound_literal, false); + if (TREE_CODE (type) == ARRAY_TYPE + && TYPE_DOMAIN (type) == NULL_TREE) + { + cp_complete_array_type_or_error (&type, compound_literal, + false, complain); + if (type == error_mark_node) + return error_mark_node; + } compound_literal = digest_init (type, compound_literal); /* Put static/constant array temporaries in static variables, but always represent class temporaries with TARGET_EXPR so we elide copies. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6612d86..c5efa1b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,7 @@ 2011-04-11 Jason Merrill <jason@redhat.com> + * g++.dg/cpp0x/sfinae12.C: New. + * g++.dg/cpp0x/enum10.C: New. * g++.dg/cpp0x/lambda/lambda-this4.C: New. diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae12.C b/gcc/testsuite/g++.dg/cpp0x/sfinae12.C new file mode 100644 index 0000000..114f1b4 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/sfinae12.C @@ -0,0 +1,18 @@ +// PR c++/48535 +// { dg-options -std=c++0x } + +template<class T, + class = decltype(T{}) +> +char f(int); + +template<class> +char (&f(...))[2]; + +struct A { virtual ~A() = 0; }; + +static_assert(sizeof(f<A>(0)) != 1, "Error"); // (a) +static_assert(sizeof(f<void()>(0)) != 1, "Error"); // (b) +static_assert(sizeof(f<int&>(0)) != 1, "Error"); // (d) +static_assert(sizeof(f<const int&>(0)) == 1, "Error"); // (e) +static_assert(sizeof(f<int[]>(0)) != 1, "Error"); // (f) |