From: dodji Date: Tue, 2 Nov 2010 12:58:48 +0000 (+0000) Subject: Fix PR c++/46170, c++/46162 X-Git-Url: http://git.sourceforge.jp/view?a=commitdiff_plain;h=ded4d0a150f1ba14174c216326ac1e5f67114388;p=pf3gnuchains%2Fgcc-fork.git Fix PR c++/46170, c++/46162 gcc/cp/ChangeLog: PR c++/46170 PR c++/46162 * pt.c (check_valid_ptrmem_cst_expr): Add a complain parameter to control diagnostic. (convert_nontype_argument, convert_nontype_argument): Pass the complain parameter down to check_valid_ptrmem_cst_expr. gcc/testsuite/ChangeLog: PR c++/46170 PR c++/46162 * g++.dg/template/sfinae26.C: New test. * g++.dg/template/sfinae27.C: Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@166181 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1ab6854ea8a..66b6671defd 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,13 @@ 2010-11-02 Dodji Seketeli + PR c++/46170 + PR c++/46162 + * pt.c (check_valid_ptrmem_cst_expr): Add a complain parameter to + control diagnostic. + (convert_nontype_argument, convert_nontype_argument): Pass the + complain parameter down to check_valid_ptrmem_cst_expr. + +2010-11-02 Dodji Seketeli PR c++/45606 * cp-tree.h (TEMPLATE_TYPE_PARM_SIBLING_PARMS): Remove. (struct template_parm_index_s): New field. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index e4975c6a112..21366d962e9 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5224,14 +5224,18 @@ convert_nontype_argument_function (tree type, tree expr) Emit an error otherwise. */ static bool -check_valid_ptrmem_cst_expr (tree type, tree expr) +check_valid_ptrmem_cst_expr (tree type, tree expr, + tsubst_flags_t complain) { STRIP_NOPS (expr); if (expr && (null_ptr_cst_p (expr) || TREE_CODE (expr) == PTRMEM_CST)) return true; - error ("%qE is not a valid template argument for type %qT", - expr, type); - error ("it must be a pointer-to-member of the form `&X::Y'"); + if (complain & tf_error) + { + error ("%qE is not a valid template argument for type %qT", + expr, type); + error ("it must be a pointer-to-member of the form `&X::Y'"); + } return false; } @@ -5600,7 +5604,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) /* [temp.arg.nontype] bullet 1 says the pointer to member expression must be a pointer-to-member constant. */ - if (!check_valid_ptrmem_cst_expr (type, expr)) + if (!check_valid_ptrmem_cst_expr (type, expr, complain)) return error_mark_node; /* There is no way to disable standard conversions in @@ -5632,7 +5636,7 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain) { /* [temp.arg.nontype] bullet 1 says the pointer to member expression must be a pointer-to-member constant. */ - if (!check_valid_ptrmem_cst_expr (type, expr)) + if (!check_valid_ptrmem_cst_expr (type, expr, complain)) return error_mark_node; expr = perform_qualification_conversions (type, expr); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b784b1cad8d..9e657754de5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,12 @@ 2010-11-02 Dodji Seketeli + PR c++/46170 + PR c++/46162 + * g++.dg/template/sfinae26.C: New test. + * g++.dg/template/sfinae27.C: Likewise. + +2010-11-02 Dodji Seketeli + PR c++/45606 * g++.dg/template/typedef36.C: New test. * gcc/testsuite/g++.dg/template/canon-type-9.C: Likewise. diff --git a/gcc/testsuite/g++.dg/template/sfinae26.C b/gcc/testsuite/g++.dg/template/sfinae26.C new file mode 100644 index 00000000000..41673fb48d9 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae26.C @@ -0,0 +1,34 @@ +// Origin: PR c++/46170 +// { dg-do "compile" } + +namespace util { + struct option_value { + }; + template struct options_map_impl { + typedef T options_struct_type; + typedef bool (*opt_func)(const option_value&, options_struct_type&); + template static bool set_member_constant(const option_value&, + options_struct_type&, V options_struct_type::*); + template static bool + set_member_constant(const option_value& opt, options_struct_type& t) { + return set_member_constant(opt, t, mem); + } + }; +} +struct cflat_options { + bool show_precharges; +}; +typedef util::options_map_impl options_map_impl_type; +class register_options_modifier { + typedef options_map_impl_type::opt_func modifier_type; +public: register_options_modifier(); + register_options_modifier(const char* Mode, const modifier_type COM, + const char* h); +}; +static const register_options_modifier +cflat_opt_mod_show_precharges("precharges", + &options_map_impl_type::set_member_constant, "show precharge expressions"), + cflat_opt_mod_no_show_precharges("no-" "precharges", + &options_map_impl_type::set_member_constant, "hide precharge expressions"); diff --git a/gcc/testsuite/g++.dg/template/sfinae27.C b/gcc/testsuite/g++.dg/template/sfinae27.C new file mode 100644 index 00000000000..0ecd1700dec --- /dev/null +++ b/gcc/testsuite/g++.dg/template/sfinae27.C @@ -0,0 +1,33 @@ +// Origin: PR c++/46162 + +struct small_type { char dummy; }; +struct large_type { char dummy[2]; }; + +template +struct has_foo_member_variable +{ + template struct tester; + template static small_type has_foo(tester<&U::foo> *); + template static large_type has_foo(...); + static const bool value = (sizeof(has_foo(0)) == sizeof(small_type)); +}; + +struct A +{ + static int foo() + { + return 0; + } +}; + +struct B +{ + static int foo; +}; + +void +bar() +{ + bool b = has_foo_member_variable::value; +} +