Commit d4a18018 by Jason Merrill Committed by Jason Merrill

re PR c++/56095 (Crash casting function pointer as non-type template argument)

	PR c++/56095
	* pt.c (convert_nontype_argument_function): Handle invalid input.
	(convert_nontype_argument): Likewise.

From-SVN: r195474
parent f8fe87bd
2013-01-25 Jason Merrill <jason@redhat.com> 2013-01-25 Jason Merrill <jason@redhat.com>
PR c++/56095
* pt.c (convert_nontype_argument_function): Handle invalid input.
(convert_nontype_argument): Likewise.
PR c++/56104 PR c++/56104
* typeck.c (get_member_function_from_ptrfunc): Optimize if the * typeck.c (get_member_function_from_ptrfunc): Optimize if the
dynamic type has no virtual functions. dynamic type has no virtual functions.
......
...@@ -5113,6 +5113,17 @@ convert_nontype_argument_function (tree type, tree expr) ...@@ -5113,6 +5113,17 @@ convert_nontype_argument_function (tree type, tree expr)
[...] [...]
-- the address of an object or function with external [C++11: or -- the address of an object or function with external [C++11: or
internal] linkage. */ internal] linkage. */
if (TREE_CODE (fn_no_ptr) != FUNCTION_DECL)
{
error ("%qE is not a valid template argument for type %qT", expr, type);
if (TREE_CODE (type) == POINTER_TYPE)
error ("it must be the address of a function with external linkage");
else
error ("it must be the name of a function with external linkage");
return NULL_TREE;
}
linkage = decl_linkage (fn_no_ptr); linkage = decl_linkage (fn_no_ptr);
if (cxx_dialect >= cxx0x ? linkage == lk_none : linkage != lk_external) if (cxx_dialect >= cxx0x ? linkage == lk_none : linkage != lk_external)
{ {
...@@ -5511,15 +5522,16 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) ...@@ -5511,15 +5522,16 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
could actually change the type to something more cv-qualified, could actually change the type to something more cv-qualified,
and this is not folded by convert_from_reference. */ and this is not folded by convert_from_reference. */
tree addr = TREE_OPERAND (probe, 0); tree addr = TREE_OPERAND (probe, 0);
gcc_assert (TREE_CODE (probe_type) == REFERENCE_TYPE); if (TREE_CODE (probe_type) == REFERENCE_TYPE
gcc_assert (TREE_CODE (addr) == ADDR_EXPR); && TREE_CODE (addr) == ADDR_EXPR
gcc_assert (TREE_CODE (TREE_TYPE (addr)) == POINTER_TYPE); && TREE_CODE (TREE_TYPE (addr)) == POINTER_TYPE
gcc_assert (same_type_ignoring_top_level_qualifiers_p && (same_type_ignoring_top_level_qualifiers_p
(TREE_TYPE (probe_type), (TREE_TYPE (probe_type),
TREE_TYPE (TREE_TYPE (addr)))); TREE_TYPE (TREE_TYPE (addr)))))
{
expr = TREE_OPERAND (addr, 0); expr = TREE_OPERAND (addr, 0);
expr_type = TREE_TYPE (expr); expr_type = TREE_TYPE (expr);
}
} }
} }
...@@ -5745,13 +5757,6 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) ...@@ -5745,13 +5757,6 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
expr = convert_nontype_argument_function (type, expr); expr = convert_nontype_argument_function (type, expr);
if (!expr || expr == error_mark_node) if (!expr || expr == error_mark_node)
return expr; return expr;
if (TREE_CODE (expr) != ADDR_EXPR)
{
error ("%qE is not a valid template argument for type %qT", expr, type);
error ("it must be the address of a function with external linkage");
return NULL_TREE;
}
} }
/* [temp.arg.nontype]/5, bullet 5 /* [temp.arg.nontype]/5, bullet 5
......
// PR c++/56095
int *a(void) { return 0; }
typedef void voidfn(void);
template <voidfn* b> void z1(void) {}
template <voidfn& b> void z2(void) {}
int main()
{
z1<(voidfn*)a>(); // { dg-error "" }
z1<reinterpret_cast<voidfn*>(a)>(); // { dg-error "" }
z2<(voidfn&)a>(); // { dg-error "" }
z2<reinterpret_cast<voidfn&>(a)>(); // { dg-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