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
This commit is contained in:
parent
f8fe87bd12
commit
d4a180188b
|
@ -1,5 +1,9 @@
|
|||
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
|
||||
* typeck.c (get_member_function_from_ptrfunc): Optimize if the
|
||||
dynamic type has no virtual functions.
|
||||
|
|
37
gcc/cp/pt.c
37
gcc/cp/pt.c
|
@ -5113,6 +5113,17 @@ convert_nontype_argument_function (tree type, tree expr)
|
|||
[...]
|
||||
-- the address of an object or function with external [C++11: or
|
||||
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);
|
||||
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)
|
|||
could actually change the type to something more cv-qualified,
|
||||
and this is not folded by convert_from_reference. */
|
||||
tree addr = TREE_OPERAND (probe, 0);
|
||||
gcc_assert (TREE_CODE (probe_type) == REFERENCE_TYPE);
|
||||
gcc_assert (TREE_CODE (addr) == ADDR_EXPR);
|
||||
gcc_assert (TREE_CODE (TREE_TYPE (addr)) == POINTER_TYPE);
|
||||
gcc_assert (same_type_ignoring_top_level_qualifiers_p
|
||||
(TREE_TYPE (probe_type),
|
||||
TREE_TYPE (TREE_TYPE (addr))));
|
||||
|
||||
expr = TREE_OPERAND (addr, 0);
|
||||
expr_type = TREE_TYPE (expr);
|
||||
if (TREE_CODE (probe_type) == REFERENCE_TYPE
|
||||
&& TREE_CODE (addr) == ADDR_EXPR
|
||||
&& TREE_CODE (TREE_TYPE (addr)) == POINTER_TYPE
|
||||
&& (same_type_ignoring_top_level_qualifiers_p
|
||||
(TREE_TYPE (probe_type),
|
||||
TREE_TYPE (TREE_TYPE (addr)))))
|
||||
{
|
||||
expr = TREE_OPERAND (addr, 0);
|
||||
expr_type = TREE_TYPE (expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5745,13 +5757,6 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
|
|||
expr = convert_nontype_argument_function (type, expr);
|
||||
if (!expr || expr == error_mark_node)
|
||||
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
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
// 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 "" }
|
||||
}
|
Loading…
Reference in New Issue