diff options
author | Jason Merrill <jason@redhat.com> | 2013-01-25 15:01:29 -0500 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2013-01-25 15:01:29 -0500 |
commit | d4a180188bed0a798818ef176c89048343277665 (patch) | |
tree | 06b0af402c8c86fa6bd9e2fe9b1d3aac1ff335bf | |
parent | f8fe87bd12b017e0f6be0d1103029e6d89dc7a40 (diff) | |
download | gcc-d4a180188bed0a798818ef176c89048343277665.zip gcc-d4a180188bed0a798818ef176c89048343277665.tar.gz gcc-d4a180188bed0a798818ef176c89048343277665.tar.bz2 |
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
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/pt.c | 37 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/fn-ptr2.C | 14 |
3 files changed, 39 insertions, 16 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 3d30491..1b640ff 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 01d4295..7430289 100644 --- a/gcc/cp/pt.c +++ b/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 diff --git a/gcc/testsuite/g++.dg/template/fn-ptr2.C b/gcc/testsuite/g++.dg/template/fn-ptr2.C new file mode 100644 index 0000000..742135a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/fn-ptr2.C @@ -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 "" } +} |