C++ cleanups before C++17 noexcept in types.
* 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
This commit is contained in:
parent
4ab71abd26
commit
452811eb53
5 changed files with 70 additions and 41 deletions
|
@ -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.
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
25
gcc/cp/pt.c
25
gcc/cp/pt.c
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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() { }
|
||||
|
|
Loading…
Add table
Reference in a new issue