From 2b8497cd7aef2697b00b7e57ae3ea787f7cbe251 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Thu, 7 Apr 2011 17:47:10 -0400 Subject: [PATCH] re PR c++/48449 ([C++0x][SFINAE] Hard errors during value-initialization expressions) PR c++/48449 * typeck2.c (build_functional_cast): Check complain consistently. Use build_value_init and abstract_virtuals_error_sfinae. (abstract_virtuals_error_sfinae): Split out. * cp-tree.h: Declare it. * init.c (build_new_1): Use it. (build_value_init_noctor): Handle FUNCTION_TYPE. From-SVN: r172141 --- gcc/cp/ChangeLog | 8 ++++++++ gcc/cp/cp-tree.h | 1 + gcc/cp/init.c | 8 +++++++- gcc/cp/typeck2.c | 26 +++++++++++++++++++------- gcc/testsuite/ChangeLog | 2 ++ gcc/testsuite/g++.dg/cpp0x/sfinae8.C | 14 ++++++++++++++ 6 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/sfinae8.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e194e33a7cd..7e0a596884a 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,13 @@ 2011-04-07 Jason Merrill + PR c++/48449 + * typeck2.c (build_functional_cast): Check complain consistently. + Use build_value_init and abstract_virtuals_error_sfinae. + (abstract_virtuals_error_sfinae): Split out. + * cp-tree.h: Declare it. + * init.c (build_new_1): Use it. + (build_value_init_noctor): Handle FUNCTION_TYPE. + * semantics.c (finish_decltype_type): Simplify handling of unknown type. diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 06b0b3e8990..94bd3cee016 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5596,6 +5596,7 @@ extern tree binfo_or_else (tree, tree); extern void cxx_readonly_error (tree, enum lvalue_use); extern void complete_type_check_abstract (tree); extern int abstract_virtuals_error (tree, tree); +extern int abstract_virtuals_error_sfinae (tree, tree, tsubst_flags_t); extern tree store_init_value (tree, tree, int); extern void check_narrowing (tree, tree); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index e1961c8ee77..2e9eb680799 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -458,6 +458,12 @@ build_value_init_noctor (tree type, tsubst_flags_t complain) /* Build a constructor to contain the initializations. */ return build_constructor (type, v); } + else if (TREE_CODE (type) == FUNCTION_TYPE) + { + if (complain & tf_error) + error ("value-initialization of function type %qT", type); + return error_mark_node; + } return build_zero_init (type, NULL_TREE, /*static_storage_p=*/false); } @@ -2030,7 +2036,7 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, return error_mark_node; } - if (abstract_virtuals_error (NULL_TREE, elt_type)) + if (abstract_virtuals_error_sfinae (NULL_TREE, elt_type, complain)) return error_mark_node; is_initialized = (TYPE_NEEDS_CONSTRUCTING (elt_type) || *init != NULL); diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 82218f0b806..f2046f7e221 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -250,7 +250,7 @@ complete_type_check_abstract (tree type) occurred; zero if all was well. */ int -abstract_virtuals_error (tree decl, tree type) +abstract_virtuals_error_sfinae (tree decl, tree type, tsubst_flags_t complain) { VEC(tree,gc) *pure; @@ -301,11 +301,14 @@ abstract_virtuals_error (tree decl, tree type) if (!pure) return 0; + if (decl && TREE_CODE (decl) == RESULT_DECL) + return 0; + + if (!(complain & tf_error)) + return 1; + if (decl) { - if (TREE_CODE (decl) == RESULT_DECL) - return 0; - if (TREE_CODE (decl) == VAR_DECL) error ("cannot declare variable %q+D to be of abstract " "type %qT", decl, type); @@ -354,6 +357,14 @@ abstract_virtuals_error (tree decl, tree type) return 1; } +/* Wrapper for the above function in the common case of wanting errors. */ + +int +abstract_virtuals_error (tree decl, tree type) +{ + return abstract_virtuals_error_sfinae (decl, type, tf_warning_or_error); +} + /* Print an error message for invalid use of an incomplete type. VALUE is the expression that was used (or 0 if that isn't known) and TYPE is the type that was invalid. DIAG_KIND indicates the @@ -1527,7 +1538,8 @@ build_functional_cast (tree exp, tree parms, tsubst_flags_t complain) if (TREE_CODE (type) == REFERENCE_TYPE && !parms) { - error ("invalid value-initialization of reference type"); + if (complain & tf_error) + error ("invalid value-initialization of reference type"); return error_mark_node; } @@ -1542,7 +1554,7 @@ build_functional_cast (tree exp, tree parms, tsubst_flags_t complain) if (! MAYBE_CLASS_TYPE_P (type)) { if (parms == NULL_TREE) - return cp_convert (type, integer_zero_node); + return build_value_init (type, complain); /* This must build a C cast. */ parms = build_x_compound_expr_from_list (parms, ELK_FUNC_CAST, complain); @@ -1558,7 +1570,7 @@ build_functional_cast (tree exp, tree parms, tsubst_flags_t complain) if (!complete_type_or_maybe_complain (type, NULL_TREE, complain)) return error_mark_node; - if (abstract_virtuals_error (NULL_TREE, type)) + if (abstract_virtuals_error_sfinae (NULL_TREE, type, complain)) return error_mark_node; /* [expr.type.conv] diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9d5f63d1a17..7aace9fd007 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,7 @@ 2011-04-07 Jason Merrill + * g++.dg/cpp0x/sfinae8.C: New. + * g++.dg/cpp0x/sfinae7.C: New. * g++.dg/cpp0x/enum9.C: New. diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae8.C b/gcc/testsuite/g++.dg/cpp0x/sfinae8.C new file mode 100644 index 00000000000..7f3012f94df --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/sfinae8.C @@ -0,0 +1,14 @@ +// PR c++/48449 +// { dg-options -std=c++0x } + +template +char f(int); + +template +char (&f(...))[2]; + +struct A { virtual ~A() = 0; }; + +static_assert(sizeof(f(0)) != 1, "Error"); +static_assert(sizeof(f(0)) != 1, "Error"); +static_assert(sizeof(f(0)) != 1, "Error"); -- 2.30.2