C++ cleanups before C++17 noexcept in types.
authorJason Merrill <jason@redhat.com>
Mon, 7 Nov 2016 23:09:21 +0000 (18:09 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 7 Nov 2016 23:09:21 +0000 (18:09 -0500)
* call.c (standard_conversion): Reorganize pointer conversions.
* pt.c (convert_nontype_argument_function): Convert to ref here.
(convert_nontype_argument): Not here.
(convert_template_argument): Add original type to error message.
(RECUR_AND_CHECK_FAILURE): Remove trailing semicolon.
(unify): Compare function-qualifiers.
* typeck.c (same_type_ignoring_top_level_qualifiers_p): Use
cp_build_qualified_type rather than TYPE_MAIN_VARIANT.

From-SVN: r241943

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/pt.c
gcc/cp/typeck.c
gcc/testsuite/g++.dg/template/func2.C

index 6f063e7534aff0a3dd34dce7ea6a9249dad82b25..a65ddec3343b5d6c03347c13710d6f6e4d1f70a6 100644 (file)
@@ -1,5 +1,14 @@
 2016-11-07  Jason Merrill  <jason@redhat.com>
 
+       * call.c (standard_conversion): Reorganize pointer conversions.
+       * pt.c (convert_nontype_argument_function): Convert to ref here.
+       (convert_nontype_argument): Not here.
+       (convert_template_argument): Add original type to error message.
+       (RECUR_AND_CHECK_FAILURE): Remove trailing semicolon.
+       (unify): Compare function-qualifiers.
+       * typeck.c (same_type_ignoring_top_level_qualifiers_p): Use
+       cp_build_qualified_type rather than TYPE_MAIN_VARIANT.
+
        * pt.c (push_tinst_level_loc): Add template instantiations to the
        announce_function stream.
 
index d2e99bccf5ab4ba573b289010d1801ece8f813fd..0466cd13e3824f3f31308c087bc08ddcf29270db 100644 (file)
@@ -1212,19 +1212,40 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
       tree to_pointee;
       tree from_pointee;
 
+      if (tcode == POINTER_TYPE)
+       {
+         to_pointee = TREE_TYPE (to);
+         from_pointee = TREE_TYPE (from);
+
+         /* Since this is the target of a pointer, it can't have function
+            qualifiers, so any TYPE_QUALS must be for attributes const or
+            noreturn.  Strip them.  */
+         if (TREE_CODE (to_pointee) == FUNCTION_TYPE
+             && TYPE_QUALS (to_pointee))
+           to_pointee = build_qualified_type (to_pointee, TYPE_UNQUALIFIED);
+         if (TREE_CODE (from_pointee) == FUNCTION_TYPE
+             && TYPE_QUALS (from_pointee))
+           from_pointee = build_qualified_type (from_pointee, TYPE_UNQUALIFIED);
+       }
+      else
+       {
+         to_pointee = TYPE_PTRMEM_POINTED_TO_TYPE (to);
+         from_pointee = TYPE_PTRMEM_POINTED_TO_TYPE (from);
+       }
+
       if (tcode == POINTER_TYPE
-         && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (from),
-                                                       TREE_TYPE (to)))
+         && same_type_ignoring_top_level_qualifiers_p (from_pointee,
+                                                       to_pointee))
        ;
-      else if (VOID_TYPE_P (TREE_TYPE (to))
+      else if (VOID_TYPE_P (to_pointee)
               && !TYPE_PTRDATAMEM_P (from)
-              && TREE_CODE (TREE_TYPE (from)) != FUNCTION_TYPE)
+              && TREE_CODE (from_pointee) != FUNCTION_TYPE)
        {
          tree nfrom = TREE_TYPE (from);
          /* Don't try to apply restrict to void.  */
          int quals = cp_type_quals (nfrom) & ~TYPE_QUAL_RESTRICT;
-         from = build_pointer_type
-           (cp_build_qualified_type (void_type_node, quals));
+         from_pointee = cp_build_qualified_type (void_type_node, quals);
+         from = build_pointer_type (from_pointee);
          conv = build_conv (ck_ptr, from, conv);
        }
       else if (TYPE_PTRDATAMEM_P (from))
@@ -1234,18 +1255,16 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
 
          if (DERIVED_FROM_P (fbase, tbase)
              && (same_type_ignoring_top_level_qualifiers_p
-                 (TYPE_PTRMEM_POINTED_TO_TYPE (from),
-                  TYPE_PTRMEM_POINTED_TO_TYPE (to))))
+                 (from_pointee, to_pointee)))
            {
-             from = build_ptrmem_type (tbase,
-                                       TYPE_PTRMEM_POINTED_TO_TYPE (from));
+             from = build_ptrmem_type (tbase, from_pointee);
              conv = build_conv (ck_pmem, from, conv);
            }
          else if (!same_type_p (fbase, tbase))
            return NULL;
        }
-      else if (CLASS_TYPE_P (TREE_TYPE (from))
-              && CLASS_TYPE_P (TREE_TYPE (to))
+      else if (CLASS_TYPE_P (from_pointee)
+              && CLASS_TYPE_P (to_pointee)
               /* [conv.ptr]
 
                  An rvalue of type "pointer to cv D," where D is a
@@ -1257,38 +1276,28 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
                  that necessitates this conversion is ill-formed.
                  Therefore, we use DERIVED_FROM_P, and do not check
                  access or uniqueness.  */
-              && DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from)))
+              && DERIVED_FROM_P (to_pointee, from_pointee))
        {
-         from =
-           cp_build_qualified_type (TREE_TYPE (to),
-                                    cp_type_quals (TREE_TYPE (from)));
-         from = build_pointer_type (from);
+         from_pointee
+           = cp_build_qualified_type (to_pointee,
+                                      cp_type_quals (from_pointee));
+         from = build_pointer_type (from_pointee);
          conv = build_conv (ck_ptr, from, conv);
          conv->base_p = true;
        }
-      else if (tx_safe_fn_type_p (TREE_TYPE (from)))
+      else if (tx_safe_fn_type_p (from_pointee))
        {
          /* A prvalue of type "pointer to transaction_safe function" can be
             converted to a prvalue of type "pointer to function". */
-         tree unsafe = tx_unsafe_fn_variant (TREE_TYPE (from));
-         if (same_type_p (unsafe, TREE_TYPE (to)))
+         tree unsafe = tx_unsafe_fn_variant (from_pointee);
+         if (same_type_p (unsafe, to_pointee))
            {
+             from_pointee = unsafe;
              from = build_pointer_type (unsafe);
              conv = build_conv (ck_tsafe, from, conv);
            }
        }
 
-      if (tcode == POINTER_TYPE)
-       {
-         to_pointee = TREE_TYPE (to);
-         from_pointee = TREE_TYPE (from);
-       }
-      else
-       {
-         to_pointee = TYPE_PTRMEM_POINTED_TO_TYPE (to);
-         from_pointee = TYPE_PTRMEM_POINTED_TO_TYPE (from);
-       }
-
       if (same_type_p (from, to))
        /* OK */;
       else if (c_cast_p && comp_ptr_ttypes_const (to, from))
index f910d40055f7918bea1398e7bf0e258e209d04ba..45965aa788da53d72cdc1b1980dec3b25b5b8e0d 100644 (file)
@@ -5913,11 +5913,11 @@ convert_nontype_argument_function (tree type, tree expr,
          error ("%qE is not a valid template argument for type %qT",
                 expr, type);
          if (TYPE_PTR_P (type))
-           error ("it must be the address of a function with "
-                  "external linkage");
+           inform (input_location, "it must be the address of a function "
+                   "with external linkage");
          else
-           error ("it must be the name of a function with "
-                  "external linkage");
+           inform (input_location, "it must be the name of a function with "
+                   "external linkage");
        }
       return NULL_TREE;
     }
@@ -5939,6 +5939,11 @@ convert_nontype_argument_function (tree type, tree expr,
       return NULL_TREE;
     }
 
+  if (TREE_CODE (type) == REFERENCE_TYPE)
+    fn = build_address (fn);
+  if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (fn)))
+    fn = build_nop (type, fn);
+
   return fn;
 }
 
@@ -6648,8 +6653,6 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
        expr = convert_nontype_argument_function (type, expr, complain);
       if (!expr || expr == error_mark_node)
        return expr;
-
-      expr = build_nop (type, build_address (expr));
     }
   /* [temp.arg.nontype]/5, bullet 6
 
@@ -7325,7 +7328,8 @@ convert_template_argument (tree parm,
       if (val == NULL_TREE)
        val = error_mark_node;
       else if (val == error_mark_node && (complain & tf_error))
-       error ("could not convert template argument %qE to %qT",  orig_arg, t);
+       error ("could not convert template argument %qE from %qT to %qT",
+              orig_arg, TREE_TYPE (orig_arg), t);
 
       if (INDIRECT_REF_P (val))
         {
@@ -19354,7 +19358,7 @@ template_parm_level_and_index (tree parm, int* level, int* index)
   do {                                                                 \
     if (unify (TP, TA, P, A, S, EP))                                   \
       return 1;                                                                \
-  } while (0);
+  } while (0)
 
 /* Unifies the remaining arguments in PACKED_ARGS with the pack
    expansion at the end of PACKED_PARMS. Returns 0 if the type
@@ -20312,6 +20316,11 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
                 class_of_this_parm (arg),
                 class_of_this_parm (parm))))
          return unify_cv_qual_mismatch (explain_p, parm, arg);
+       if (TREE_CODE (arg) == FUNCTION_TYPE
+           && type_memfn_quals (parm) != type_memfn_quals (arg))
+         return unify_cv_qual_mismatch (explain_p, parm, arg);
+       if (type_memfn_rqual (parm) != type_memfn_rqual (arg))
+         return unify_type_mismatch (explain_p, parm, arg);
 
        RECUR_AND_CHECK_FAILURE (tparms, targs, TREE_TYPE (parm),
                                 TREE_TYPE (arg), UNIFY_ALLOW_NONE, explain_p);
index 45b7d264088f552d0904e21e03dce8b5e79400ae..4ff2bc2d26ecff8f5b8c6578d348bb1a5f5659a1 100644 (file)
@@ -1457,7 +1457,9 @@ same_type_ignoring_top_level_qualifiers_p (tree type1, tree type2)
   if (type1 == error_mark_node || type2 == error_mark_node)
     return false;
 
-  return same_type_p (TYPE_MAIN_VARIANT (type1), TYPE_MAIN_VARIANT (type2));
+  type1 = cp_build_qualified_type (type1, TYPE_UNQUALIFIED);
+  type2 = cp_build_qualified_type (type2, TYPE_UNQUALIFIED);
+  return same_type_p (type1, type2);
 }
 
 /* Returns 1 if TYPE1 is at least as qualified as TYPE2.  */
index b0f691d242b9f8ac0b226cdc56fb13278219e8fb..746f0e279a73c54ba3988aa7efe0eb44dd69d20e 100644 (file)
@@ -5,7 +5,7 @@ fptr zeroptr = 0;
 template<typename T, fptr F> struct foo { };
 template<typename T> struct foo<T,zeroptr> { };
 // { dg-error "not a valid template argument" "not valid" { target *-*-* } 6 } 
-// { dg-error "must be the address" "must be the address " { target *-*-* } 6 }
+// { dg-message "must be the address" "must be the address " { target *-*-* } 6 }
 
 // The rest is needed to trigger the ICE in 4.0 to 4.3:
 void f() { }