OSDN Git Service

PR c++/58119
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 20 Aug 2013 12:59:24 +0000 (12:59 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 20 Aug 2013 12:59:24 +0000 (12:59 +0000)
* cp-tree.h (WILDCARD_TYPE_P): Split out from...
(MAYBE_CLASS_TYPE_P): ...here.
* cvt.c (build_expr_type_conversion): Don't complain about a
template that can't match the desired type category.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_7-branch@201881 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 5b5acd9..2473442 100644 (file)
@@ -1,3 +1,11 @@
+2013-08-20  Jason Merrill  <jason@redhat.com>
+
+       PR c++/58119
+       * cp-tree.h (WILDCARD_TYPE_P): Split out from...
+       (MAYBE_CLASS_TYPE_P): ...here.
+       * cvt.c (build_expr_type_conversion): Don't complain about a
+       template that can't match the desired type category.
+
 2012-12-03  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/54170
index 0c1601b..b4fdda7 100644 (file)
@@ -1191,17 +1191,20 @@ enum languages { lang_c, lang_cplusplus, lang_java };
 /* The _DECL for this _TYPE.  */
 #define TYPE_MAIN_DECL(NODE) (TYPE_STUB_DECL (TYPE_MAIN_VARIANT (NODE)))
 
-/* Nonzero if T is a class (or struct or union) type.  Also nonzero
-   for template type parameters, typename types, and instantiated
-   template template parameters.  Keep these checks in ascending code
-   order.  */
-#define MAYBE_CLASS_TYPE_P(T)                                  \
+/* Nonzero if T is a type that could resolve to any kind of concrete type
+   at instantiation time.  */
+#define WILDCARD_TYPE_P(T)                             \
   (TREE_CODE (T) == TEMPLATE_TYPE_PARM                 \
    || TREE_CODE (T) == TYPENAME_TYPE                   \
    || TREE_CODE (T) == TYPEOF_TYPE                     \
    || TREE_CODE (T) == BOUND_TEMPLATE_TEMPLATE_PARM    \
-   || TREE_CODE (T) == DECLTYPE_TYPE                   \
-   || CLASS_TYPE_P (T))
+   || TREE_CODE (T) == DECLTYPE_TYPE)
+
+/* Nonzero if T is a class (or struct or union) type.  Also nonzero
+   for template type parameters, typename types, and instantiated
+   template template parameters.  Keep these checks in ascending code
+   order.  */
+#define MAYBE_CLASS_TYPE_P(T) (WILDCARD_TYPE_P (T) || CLASS_TYPE_P (T))
 
 /* Set CLASS_TYPE_P for T to VAL.  T must be a class, struct, or
    union type.  */
index d7ad05b..fddba51 100644 (file)
@@ -1539,17 +1539,6 @@ build_expr_type_conversion (int desires, tree expr, bool complain)
       if (DECL_NONCONVERTING_P (cand))
        continue;
 
-      if (TREE_CODE (cand) == TEMPLATE_DECL)
-       {
-         if (complain)
-           {
-             error ("ambiguous default type conversion from %qT",
-                    basetype);
-             error ("  candidate conversions include %qD", cand);
-           }
-         return error_mark_node;
-       }
-
       candidate = non_reference (TREE_TYPE (TREE_TYPE (cand)));
 
       switch (TREE_CODE (candidate))
@@ -1583,11 +1572,23 @@ build_expr_type_conversion (int desires, tree expr, bool complain)
          break;
 
        default:
+         /* A wildcard could be instantiated to match any desired
+            type, but we can't deduce the template argument.  */
+         if (WILDCARD_TYPE_P (candidate))
+           win = true;
          break;
        }
 
       if (win)
        {
+         if (TREE_CODE (cand) == TEMPLATE_DECL)
+           {
+             if (complain)
+               error ("default type conversion can't deduce template"
+                      " argument for %qD", cand);
+             return error_mark_node;
+           }
+
          if (winner)
            {
              if (complain)
diff --git a/gcc/testsuite/g++.dg/template/delete2.C b/gcc/testsuite/g++.dg/template/delete2.C
new file mode 100644 (file)
index 0000000..b6ab380
--- /dev/null
@@ -0,0 +1,26 @@
+// PR c++/58119
+
+template <class T>
+struct A
+{
+  operator T*();
+  template <class U>
+  operator A<U>();
+};
+
+template <class T>
+struct B
+{
+  operator T*();
+  template <class U>
+  operator A<U>*();
+};
+
+int main()
+{
+  A<int> a;
+  delete a;
+
+  B<int> b;
+  delete b;                    // { dg-error "template|delete" }
+}