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
2010-11-02 Dodji Seketeli <dodji@redhat.com>
+ 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 <dodji@redhat.com>
PR c++/45606
* cp-tree.h (TEMPLATE_TYPE_PARM_SIBLING_PARMS): Remove.
(struct template_parm_index_s)<num_siblings>: New field.
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;
}
/* [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
{
/* [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);
2010-11-02 Dodji Seketeli <dodji@redhat.com>
+ PR c++/46170
+ PR c++/46162
+ * g++.dg/template/sfinae26.C: New test.
+ * g++.dg/template/sfinae27.C: Likewise.
+
+2010-11-02 Dodji Seketeli <dodji@redhat.com>
+
PR c++/45606
* g++.dg/template/typedef36.C: New test.
* gcc/testsuite/g++.dg/template/canon-type-9.C: Likewise.
--- /dev/null
+// Origin: PR c++/46170
+// { dg-do "compile" }
+
+namespace util {
+ struct option_value {
+ };
+ template <class T> struct options_map_impl {
+ typedef T options_struct_type;
+ typedef bool (*opt_func)(const option_value&, options_struct_type&);
+ template <class V, V K> static bool set_member_constant(const option_value&,
+ options_struct_type&, V options_struct_type::*);
+ template <class V, V options_struct_type::*mem, V K> static bool
+ set_member_constant(const option_value& opt, options_struct_type& t) {
+ return set_member_constant<V,K>(opt, t, mem);
+ }
+ };
+}
+struct cflat_options {
+ bool show_precharges;
+};
+typedef util::options_map_impl<cflat_options> 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<bool,
+ &cflat_options::show_precharges, true>, "show precharge expressions"),
+ cflat_opt_mod_no_show_precharges("no-" "precharges",
+ &options_map_impl_type::set_member_constant<bool,
+ &cflat_options::show_precharges, false>, "hide precharge expressions");
--- /dev/null
+// Origin: PR c++/46162
+
+struct small_type { char dummy; };
+struct large_type { char dummy[2]; };
+
+template<class T>
+struct has_foo_member_variable
+{
+ template<int T::*> struct tester;
+ template<class U> static small_type has_foo(tester<&U::foo> *);
+ template<class U> static large_type has_foo(...);
+ static const bool value = (sizeof(has_foo<T>(0)) == sizeof(small_type));
+};
+
+struct A
+{
+ static int foo()
+ {
+ return 0;
+ }
+};
+
+struct B
+{
+ static int foo;
+};
+
+void
+bar()
+{
+ bool b = has_foo_member_variable<A>::value;
+}
+