Commit 2b8497cd by Jason Merrill Committed by Jason Merrill

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
parent 6cdb1428
2011-04-07 Jason Merrill <jason@redhat.com>
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.
......
......@@ -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);
......
......@@ -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);
......
......@@ -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]
......
2011-04-07 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/sfinae8.C: New.
* g++.dg/cpp0x/sfinae7.C: New.
* g++.dg/cpp0x/enum9.C: New.
......
// PR c++/48449
// { 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<int&>(0)) != 1, "Error");
static_assert(sizeof(f<void()>(0)) != 1, "Error");
static_assert(sizeof(f<A>(0)) != 1, "Error");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment