mirror of git://gcc.gnu.org/git/gcc.git
Core DR 342 PR c++/48582
Core DR 342 PR c++/48582 * pt.c (check_valid_ptrmem_cst_expr): A null member pointer value is valid in C++11. (convert_nontype_argument): Likewise. Implicitly convert nullptr and do constant folding. * mangle.c (write_template_arg_literal): Mangle null member pointer values as 0. * call.c (null_member_pointer_value_p): New. * cp-tree.h: Declare it. From-SVN: r178144
This commit is contained in:
parent
2aef967bc8
commit
e90abaa0a2
|
|
@ -1,3 +1,16 @@
|
||||||
|
2011-08-26 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
|
Core DR 342
|
||||||
|
PR c++/48582
|
||||||
|
* pt.c (check_valid_ptrmem_cst_expr): A null member pointer value
|
||||||
|
is valid in C++11.
|
||||||
|
(convert_nontype_argument): Likewise. Implicitly convert nullptr
|
||||||
|
and do constant folding.
|
||||||
|
* mangle.c (write_template_arg_literal): Mangle null member
|
||||||
|
pointer values as 0.
|
||||||
|
* call.c (null_member_pointer_value_p): New.
|
||||||
|
* cp-tree.h: Declare it.
|
||||||
|
|
||||||
2011-08-25 Jason Merrill <jason@redhat.com>
|
2011-08-25 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
* call.c (convert_like_real): Remove redundant complain checks.
|
* call.c (convert_like_real): Remove redundant complain checks.
|
||||||
|
|
|
||||||
|
|
@ -553,6 +553,23 @@ null_ptr_cst_p (tree t)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns true iff T is a null member pointer value (4.11). */
|
||||||
|
|
||||||
|
bool
|
||||||
|
null_member_pointer_value_p (tree t)
|
||||||
|
{
|
||||||
|
tree type = TREE_TYPE (t);
|
||||||
|
if (!type)
|
||||||
|
return false;
|
||||||
|
else if (TYPE_PTRMEMFUNC_P (type))
|
||||||
|
return (TREE_CODE (t) == CONSTRUCTOR
|
||||||
|
&& integer_zerop (CONSTRUCTOR_ELT (t, 0)->value));
|
||||||
|
else if (TYPE_PTRMEM_P (type))
|
||||||
|
return integer_all_onesp (t);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Returns nonzero if PARMLIST consists of only default parms,
|
/* Returns nonzero if PARMLIST consists of only default parms,
|
||||||
ellipsis, and/or undeduced parameter packs. */
|
ellipsis, and/or undeduced parameter packs. */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4722,6 +4722,7 @@ extern tree build_addr_func (tree);
|
||||||
extern tree build_call_a (tree, int, tree*);
|
extern tree build_call_a (tree, int, tree*);
|
||||||
extern tree build_call_n (tree, int, ...);
|
extern tree build_call_n (tree, int, ...);
|
||||||
extern bool null_ptr_cst_p (tree);
|
extern bool null_ptr_cst_p (tree);
|
||||||
|
extern bool null_member_pointer_value_p (tree);
|
||||||
extern bool sufficient_parms_p (const_tree);
|
extern bool sufficient_parms_p (const_tree);
|
||||||
extern tree type_decays_to (tree);
|
extern tree type_decays_to (tree);
|
||||||
extern tree build_user_type_conversion (tree, tree, int);
|
extern tree build_user_type_conversion (tree, tree, int);
|
||||||
|
|
|
||||||
|
|
@ -2762,6 +2762,11 @@ write_template_arg_literal (const tree value)
|
||||||
write_char ('L');
|
write_char ('L');
|
||||||
write_type (TREE_TYPE (value));
|
write_type (TREE_TYPE (value));
|
||||||
|
|
||||||
|
/* Write a null member pointer value as (type)0, regardless of its
|
||||||
|
real representation. */
|
||||||
|
if (null_member_pointer_value_p (value))
|
||||||
|
write_integer_cst (integer_zero_node);
|
||||||
|
else
|
||||||
switch (TREE_CODE (value))
|
switch (TREE_CODE (value))
|
||||||
{
|
{
|
||||||
case CONST_DECL:
|
case CONST_DECL:
|
||||||
|
|
@ -2845,7 +2850,8 @@ write_template_arg (tree node)
|
||||||
/* A template appearing as a template arg is a template template arg. */
|
/* A template appearing as a template arg is a template template arg. */
|
||||||
write_template_template_arg (node);
|
write_template_template_arg (node);
|
||||||
else if ((TREE_CODE_CLASS (code) == tcc_constant && code != PTRMEM_CST)
|
else if ((TREE_CODE_CLASS (code) == tcc_constant && code != PTRMEM_CST)
|
||||||
|| (abi_version_at_least (2) && code == CONST_DECL))
|
|| (abi_version_at_least (2) && code == CONST_DECL)
|
||||||
|
|| null_member_pointer_value_p (node))
|
||||||
write_template_arg_literal (node);
|
write_template_arg_literal (node);
|
||||||
else if (DECL_P (node))
|
else if (DECL_P (node))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
19
gcc/cp/pt.c
19
gcc/cp/pt.c
|
|
@ -5240,6 +5240,8 @@ check_valid_ptrmem_cst_expr (tree type, tree expr,
|
||||||
STRIP_NOPS (expr);
|
STRIP_NOPS (expr);
|
||||||
if (expr && (null_ptr_cst_p (expr) || TREE_CODE (expr) == PTRMEM_CST))
|
if (expr && (null_ptr_cst_p (expr) || TREE_CODE (expr) == PTRMEM_CST))
|
||||||
return true;
|
return true;
|
||||||
|
if (cxx_dialect >= cxx0x && null_member_pointer_value_p (expr))
|
||||||
|
return true;
|
||||||
if (complain & tf_error)
|
if (complain & tf_error)
|
||||||
{
|
{
|
||||||
error ("%qE is not a valid template argument for type %qT",
|
error ("%qE is not a valid template argument for type %qT",
|
||||||
|
|
@ -5550,6 +5552,17 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
|
||||||
else
|
else
|
||||||
expr = mark_rvalue_use (expr);
|
expr = mark_rvalue_use (expr);
|
||||||
|
|
||||||
|
/* 14.3.2/5: The null pointer{,-to-member} conversion is applied
|
||||||
|
to a non-type argument of "nullptr". */
|
||||||
|
if (expr == nullptr_node
|
||||||
|
&& (TYPE_PTR_P (type) || TYPE_PTR_TO_MEMBER_P (type)))
|
||||||
|
expr = convert (type, expr);
|
||||||
|
|
||||||
|
/* In C++11, non-type template arguments can be arbitrary constant
|
||||||
|
expressions. But don't fold a PTRMEM_CST to a CONSTRUCTOR yet. */
|
||||||
|
if (cxx_dialect >= cxx0x && TREE_CODE (expr) != PTRMEM_CST)
|
||||||
|
expr = maybe_constant_value (expr);
|
||||||
|
|
||||||
/* HACK: Due to double coercion, we can get a
|
/* HACK: Due to double coercion, we can get a
|
||||||
NOP_EXPR<REFERENCE_TYPE>(ADDR_EXPR<POINTER_TYPE> (arg)) here,
|
NOP_EXPR<REFERENCE_TYPE>(ADDR_EXPR<POINTER_TYPE> (arg)) here,
|
||||||
which is the tree that we built on the first call (see
|
which is the tree that we built on the first call (see
|
||||||
|
|
@ -5658,6 +5671,8 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
|
||||||
if (DECL_P (expr) && DECL_TEMPLATE_PARM_P (expr))
|
if (DECL_P (expr) && DECL_TEMPLATE_PARM_P (expr))
|
||||||
/* Non-type template parameters are OK. */
|
/* Non-type template parameters are OK. */
|
||||||
;
|
;
|
||||||
|
else if (cxx_dialect >= cxx0x && integer_zerop (expr))
|
||||||
|
/* Null pointer values are OK in C++11. */;
|
||||||
else if (TREE_CODE (expr) != ADDR_EXPR
|
else if (TREE_CODE (expr) != ADDR_EXPR
|
||||||
&& TREE_CODE (expr_type) != ARRAY_TYPE)
|
&& TREE_CODE (expr_type) != ARRAY_TYPE)
|
||||||
{
|
{
|
||||||
|
|
@ -5785,6 +5800,10 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cxx_dialect >= cxx0x && integer_zerop (expr))
|
||||||
|
/* Null pointer values are OK in C++11. */
|
||||||
|
return perform_qualification_conversions (type, expr);
|
||||||
|
|
||||||
expr = convert_nontype_argument_function (type, expr);
|
expr = convert_nontype_argument_function (type, expr);
|
||||||
if (!expr || expr == error_mark_node)
|
if (!expr || expr == error_mark_node)
|
||||||
return expr;
|
return expr;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
2011-08-26 Jason Merrill <jason@redhat.com>
|
||||||
|
|
||||||
|
Core DR 342
|
||||||
|
PR c++/48582
|
||||||
|
* g++.dg/abi/mangle50.C: New.
|
||||||
|
|
||||||
2011-08-27 Uros Bizjak <ubizjak@gmail.com>
|
2011-08-27 Uros Bizjak <ubizjak@gmail.com>
|
||||||
|
|
||||||
PR target/50202
|
PR target/50202
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
// DR 342, PR c++/48582
|
||||||
|
// { dg-options -std=c++0x }
|
||||||
|
|
||||||
|
struct A;
|
||||||
|
template < void * = nullptr > void f() { }
|
||||||
|
template < void (A::*)() = nullptr > void g() { }
|
||||||
|
template < int A::* = nullptr > void h() { }
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// { dg-final { scan-assembler "_Z1fILPv0EEvv" } }
|
||||||
|
f();
|
||||||
|
f<nullptr>();
|
||||||
|
|
||||||
|
// { dg-final { scan-assembler "_Z1gILM1AFvvE0EEvv" } }
|
||||||
|
g();
|
||||||
|
g<nullptr>();
|
||||||
|
|
||||||
|
// { dg-final { scan-assembler "_Z1fILPv0EEvv" } }
|
||||||
|
h();
|
||||||
|
h<nullptr>();
|
||||||
|
|
||||||
|
constexpr void * ptr = nullptr;
|
||||||
|
f<ptr>();
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue