OSDN Git Service

PR c++/41468
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 27 Apr 2010 19:04:09 +0000 (19:04 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 27 Apr 2010 19:04:09 +0000 (19:04 +0000)
* class.c (convert_to_base): Add complain parameter.  Pass
ba_quiet to lookup_base if we don't want errors.
(build_vfield_ref): Pass complain to convert_to_base.
* call.c (convert_like_real): Likewise.
(initialize_reference): Likewise.
(perform_direct_initialization_if_possible): Pass complain to
convert_like_real.
* cp-tree.h: Adjust.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158798 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/sfinae17.C [new file with mode: 0644]

index a996461..d4b82a9 100644 (file)
@@ -1,3 +1,15 @@
+2010-04-27  Jason Merrill  <jason@redhat.com>
+
+       PR c++/41468
+       * class.c (convert_to_base): Add complain parameter.  Pass
+       ba_quiet to lookup_base if we don't want errors.
+       (build_vfield_ref): Pass complain to convert_to_base.
+       * call.c (convert_like_real): Likewise.
+       (initialize_reference): Likewise.
+       (perform_direct_initialization_if_possible): Pass complain to
+       convert_like_real.
+       * cp-tree.h: Adjust.
+
 2010-04-27  Fabien ChĂȘne  <fabien.chene@gmail.com>
            Jason Merrill  <jason@redhat.com>
 
index 90f84e0..a97f7dc 100644 (file)
@@ -5019,7 +5019,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
          /* Build an expression for `*((base*) &expr)'.  */
          expr = cp_build_unary_op (ADDR_EXPR, expr, 0, complain);
          expr = convert_to_base (expr, build_pointer_type (totype),
-                                 !c_cast_p, /*nonnull=*/true);
+                                 !c_cast_p, /*nonnull=*/true, complain);
          expr = cp_build_indirect_ref (expr, RO_IMPLICIT_CONVERSION, complain);
          return expr;
        }
@@ -5142,7 +5142,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
     case ck_ptr:
       if (convs->base_p)
        expr = convert_to_base (expr, totype, !c_cast_p,
-                               /*nonnull=*/false);
+                               /*nonnull=*/false, complain);
       return build_nop (totype, expr);
 
     case ck_pmem:
@@ -7584,7 +7584,7 @@ perform_direct_initialization_if_possible (tree type,
     expr = convert_like_real (conv, expr, NULL_TREE, 0, 0,
                              /*issue_conversion_warnings=*/false,
                              c_cast_p,
-                             tf_warning_or_error);
+                             complain);
 
   /* Free all the conversions we allocated.  */
   obstack_free (&conversion_obstack, p);
@@ -7810,7 +7810,7 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup,
                expr = convert_to_base (expr,
                                        build_pointer_type (base_conv_type),
                                        /*check_access=*/true,
-                                       /*nonnull=*/true);
+                                       /*nonnull=*/true, complain);
              expr = build2 (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);
            }
          else
index 26da21b..07dfb1c 100644 (file)
@@ -506,10 +506,12 @@ build_simple_base_path (tree expr, tree binfo)
    assumed to be non-NULL.  */
 
 tree
-convert_to_base (tree object, tree type, bool check_access, bool nonnull)
+convert_to_base (tree object, tree type, bool check_access, bool nonnull,
+                tsubst_flags_t complain)
 {
   tree binfo;
   tree object_type;
+  base_access access;
 
   if (TYPE_PTR_P (TREE_TYPE (object)))
     {
@@ -519,8 +521,11 @@ convert_to_base (tree object, tree type, bool check_access, bool nonnull)
   else
     object_type = TREE_TYPE (object);
 
+  access = check_access ? ba_check : ba_unique;
+  if (!(complain & tf_error))
+    access |= ba_quiet;
   binfo = lookup_base (object_type, type,
-                      check_access ? ba_check : ba_unique,
+                      access,
                       NULL);
   if (!binfo || binfo == error_mark_node)
     return error_mark_node;
@@ -575,7 +580,7 @@ build_vfield_ref (tree datum, tree type)
   /* First, convert to the requested type.  */
   if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (datum), type))
     datum = convert_to_base (datum, type, /*check_access=*/false,
-                            /*nonnull=*/true);
+                            /*nonnull=*/true, tf_warning_or_error);
 
   /* Second, the requested type may not be the owner of its own vptr.
      If not, convert to the base class that owns it.  We cannot use
index a7ed134..dd89171 100644 (file)
@@ -4569,7 +4569,8 @@ extern void validate_conversion_obstack           (void);
 extern tree build_vfield_ref                   (tree, tree);
 extern tree build_base_path                    (enum tree_code, tree,
                                                 tree, int);
-extern tree convert_to_base                    (tree, tree, bool, bool);
+extern tree convert_to_base                    (tree, tree, bool, bool,
+                                                tsubst_flags_t);
 extern tree convert_to_base_statically         (tree, tree);
 extern tree build_vtbl_ref                     (tree, tree);
 extern tree build_vfn_ref                      (tree, tree);
index 21d9e0d..ce7206a 100644 (file)
@@ -1,3 +1,8 @@
+2010-04-27  Jason Merrill  <jason@redhat.com>
+
+       PR c++/41468
+       * g++.dg/template/sfinae17.C: New.
+
 2010-04-27  Fabien ChĂȘne  <fabien.chene@gmail.com>
 
        * g++.dg/init/pr42844.C: New.
diff --git a/gcc/testsuite/g++.dg/template/sfinae17.C b/gcc/testsuite/g++.dg/template/sfinae17.C
new file mode 100644 (file)
index 0000000..eb043cb
--- /dev/null
@@ -0,0 +1,28 @@
+// The conversion from D* to B* is ambiguous, but that should not produce
+// an error, it should remove the first f overload by SFINAE.
+
+#define static_assert(TEST,STR) \
+  do { int ar[(TEST)?1:-1]; } while (0);
+
+struct B {};
+
+struct B1 : B {};
+struct B2 : B {};
+
+struct D : B1, B2 {};
+
+template <class T> T create();
+
+typedef char one[1];
+typedef char two[2];
+
+template <class T>
+    one &f(char (*)[sizeof static_cast<T>(create<D *>())]);
+template <class T>
+    two &f(...);
+
+int main()
+{
+  static_assert(sizeof f<int>(0) == sizeof(two), "");
+  static_assert(sizeof f<B *>(0) == sizeof(two), "");
+}