OSDN Git Service

Fix PR c++/46170, c++/46162
authordodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 2 Nov 2010 12:58:48 +0000 (12:58 +0000)
committerdodji <dodji@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 2 Nov 2010 12:58:48 +0000 (12:58 +0000)
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

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/sfinae26.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/sfinae27.C [new file with mode: 0644]

index 1ab6854..66b6671 100644 (file)
@@ -1,5 +1,13 @@
 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.
index e4975c6..21366d9 100644 (file)
@@ -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);
index b784b1c..9e65775 100644 (file)
@@ -1,5 +1,12 @@
 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.
diff --git a/gcc/testsuite/g++.dg/template/sfinae26.C b/gcc/testsuite/g++.dg/template/sfinae26.C
new file mode 100644 (file)
index 0000000..41673fb
--- /dev/null
@@ -0,0 +1,34 @@
+// 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");
diff --git a/gcc/testsuite/g++.dg/template/sfinae27.C b/gcc/testsuite/g++.dg/template/sfinae27.C
new file mode 100644 (file)
index 0000000..0ecd170
--- /dev/null
@@ -0,0 +1,33 @@
+// 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;
+}
+