This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][C++] Move decltype(nullptr) back to NULLPTR_TYPE tree code
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: jason at redhat dot com
- Date: Wed, 13 Oct 2010 17:05:46 +0200 (CEST)
- Subject: [PATCH][C++] Move decltype(nullptr) back to NULLPTR_TYPE tree code
This moves back to using a new tree code for NULLPTR_TYPE instead of
LANG_TYPE. Due to the previously noted issues this is now a common
tree code, otherwise I basically reverted the patch that transitioned
nullptr to LANG_TYPE.
See alsothe audit-trail of PR44561 that motivates this change
(LTO doesn't play well with LANG_TYPE).
Sofar only lightly tested - Jason, is this ok with you? I'll do
some more testing, including libstdc++ with LTO tomorrow.
Thanks,
Richard.
2010-10-13 Richard Guenther <rguenther@suse.de>
PR lto/44561
* tree.def (NULLPTR_TYPE): New tree code.
* dbxout.c (dbxout_type): Handle NULLPTR_TYPE.
* dwarf2out.c (is_base_type): Likewise.
(gen_type_die_with_usage): Likewise.
* sdbout.c (plain_type_1): Likewise.
* tree.c (build_int_cst_wide): Likewise.
* gimple.c (gimple_types_compatible_p_1): NULLPTR_TYPE types
are equal.
cp/
* cp-tree.h (NULLPTR_TYPE_P): Adjust.
* decl.c (cxx_init_decl_processing): Build a NULLPTR_TYPE node,
use build_int_cst.
* error.c (dump_type): Handle NULLPTR_TYPE.
(dump_type_prefix): Likewise.
(dump_type_suffix): Likewise.
* mangle.c (write_type): Likewise.
* name-lookup.c (arg_assoc_type): Likewise.
* rtti.c (typeinfo_in_lib_p): Likewise.
* g++.dg/lto/20101010-3_0.C: New testcase.
* g++.dg/lto/20101010-4_0.C: Likewise.
Index: gcc/testsuite/g++.dg/lto/20101010-3_0.C
===================================================================
*** /dev/null 1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/g++.dg/lto/20101010-3_0.C 2010-10-13 15:24:27.000000000 +0200
***************
*** 0 ****
--- 1,5 ----
+ // { dg-lto-do link }
+ // { dg-lto-options { "-flto -std=c++0x" } }
+
+ decltype(nullptr) a;
+ int main() { return 0; }
Index: gcc/testsuite/g++.dg/lto/20101010-4_0.C
===================================================================
*** /dev/null 1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/g++.dg/lto/20101010-4_0.C 2010-10-13 15:24:27.000000000 +0200
***************
*** 0 ****
--- 1,9 ----
+ // { dg-lto-do link }
+ // { dg-lto-options { { -flto -r -nostdlib } { -flto -g -r -nostdlib } } }
+
+ typedef decltype(nullptr) nullptr_t;
+ class shared_ptr {
+ public:
+ shared_ptr(nullptr_t __p);
+ };
+ shared_ptr p = nullptr;
Index: gcc/cp/cp-tree.h
===================================================================
*** gcc/cp/cp-tree.h.orig 2010-10-12 11:47:25.000000000 +0200
--- gcc/cp/cp-tree.h 2010-10-13 15:29:25.000000000 +0200
*************** more_aggr_init_expr_args_p (const aggr_i
*** 3051,3059 ****
|| TREE_CODE (TYPE) == COMPLEX_TYPE)
/* True iff TYPE is cv decltype(nullptr). */
! #define NULLPTR_TYPE_P(TYPE) \
! (TREE_CODE (TYPE) == LANG_TYPE \
! && TYPE_MAIN_VARIANT (TYPE) == nullptr_type_node)
/* [basic.types]
--- 3051,3057 ----
|| TREE_CODE (TYPE) == COMPLEX_TYPE)
/* True iff TYPE is cv decltype(nullptr). */
! #define NULLPTR_TYPE_P(TYPE) (TREE_CODE (TYPE) == NULLPTR_TYPE)
/* [basic.types]
Index: gcc/cp/decl.c
===================================================================
*** gcc/cp/decl.c.orig 2010-10-11 13:56:57.000000000 +0200
--- gcc/cp/decl.c 2010-10-13 15:31:11.000000000 +0200
*************** cxx_init_decl_processing (void)
*** 3552,3566 ****
global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype);
push_cp_library_fn (VEC_DELETE_EXPR, deltype);
! nullptr_type_node = make_node (LANG_TYPE);
TYPE_SIZE (nullptr_type_node) = bitsize_int (GET_MODE_BITSIZE (ptr_mode));
TYPE_SIZE_UNIT (nullptr_type_node) = size_int (GET_MODE_SIZE (ptr_mode));
TYPE_UNSIGNED (nullptr_type_node) = 1;
TYPE_PRECISION (nullptr_type_node) = GET_MODE_BITSIZE (ptr_mode);
SET_TYPE_MODE (nullptr_type_node, Pmode);
record_builtin_type (RID_MAX, "decltype(nullptr)", nullptr_type_node);
! nullptr_node = make_node (INTEGER_CST);
! TREE_TYPE (nullptr_node) = nullptr_type_node;
}
abort_fndecl
--- 3552,3565 ----
global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype);
push_cp_library_fn (VEC_DELETE_EXPR, deltype);
! nullptr_type_node = make_node (NULLPTR_TYPE);
TYPE_SIZE (nullptr_type_node) = bitsize_int (GET_MODE_BITSIZE (ptr_mode));
TYPE_SIZE_UNIT (nullptr_type_node) = size_int (GET_MODE_SIZE (ptr_mode));
TYPE_UNSIGNED (nullptr_type_node) = 1;
TYPE_PRECISION (nullptr_type_node) = GET_MODE_BITSIZE (ptr_mode);
SET_TYPE_MODE (nullptr_type_node, Pmode);
record_builtin_type (RID_MAX, "decltype(nullptr)", nullptr_type_node);
! nullptr_node = build_int_cst (nullptr_type_node, 0);
}
abort_fndecl
Index: gcc/cp/error.c
===================================================================
*** gcc/cp/error.c.orig 2010-10-08 11:13:43.000000000 +0200
--- gcc/cp/error.c 2010-10-13 15:33:52.000000000 +0200
*************** dump_type (tree t, int flags)
*** 500,505 ****
--- 500,509 ----
pp_cxx_right_paren (cxx_pp);
break;
+ case NULLPTR_TYPE:
+ pp_string (cxx_pp, "std::nullptr_t");
+ break;
+
default:
pp_unsupported_tree (cxx_pp, t);
/* Fall through to error. */
*************** dump_type_prefix (tree t, int flags)
*** 728,733 ****
--- 732,738 ----
case DECLTYPE_TYPE:
case TYPE_PACK_EXPANSION:
case FIXED_POINT_TYPE:
+ case NULLPTR_TYPE:
dump_type (t, flags);
pp_base (cxx_pp)->padding = pp_before;
break;
*************** dump_type_suffix (tree t, int flags)
*** 830,835 ****
--- 835,841 ----
case DECLTYPE_TYPE:
case TYPE_PACK_EXPANSION:
case FIXED_POINT_TYPE:
+ case NULLPTR_TYPE:
break;
default:
Index: gcc/cp/mangle.c
===================================================================
*** gcc/cp/mangle.c.orig 2010-09-27 15:48:25.000000000 +0200
--- gcc/cp/mangle.c 2010-10-13 15:34:37.000000000 +0200
*************** write_type (tree type)
*** 1943,1959 ****
write_char ('E');
break;
case TYPEOF_TYPE:
sorry ("mangling typeof, use decltype instead");
break;
case LANG_TYPE:
! if (NULLPTR_TYPE_P (type))
! {
! write_string ("Dn");
! break;
! }
! /* else fall through. */
default:
gcc_unreachable ();
--- 1943,1958 ----
write_char ('E');
break;
+ case NULLPTR_TYPE:
+ write_string ("Dn");
+ break;
+
case TYPEOF_TYPE:
sorry ("mangling typeof, use decltype instead");
break;
case LANG_TYPE:
! /* fall through. */
default:
gcc_unreachable ();
Index: gcc/cp/name-lookup.c
===================================================================
*** gcc/cp/name-lookup.c.orig 2010-09-29 15:59:45.000000000 +0200
--- gcc/cp/name-lookup.c 2010-10-13 15:35:10.000000000 +0200
*************** arg_assoc_type (struct arg_lookup *k, tr
*** 4932,4937 ****
--- 4932,4938 ----
case BOOLEAN_TYPE:
case FIXED_POINT_TYPE:
case DECLTYPE_TYPE:
+ case NULLPTR_TYPE:
return false;
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (type))
*************** arg_assoc_type (struct arg_lookup *k, tr
*** 4963,4969 ****
return false;
case LANG_TYPE:
gcc_assert (type == unknown_type_node
- || NULLPTR_TYPE_P (type)
|| type == init_list_type_node);
return false;
case TYPE_PACK_EXPANSION:
--- 4964,4969 ----
Index: gcc/cp/rtti.c
===================================================================
*** gcc/cp/rtti.c.orig 2010-09-28 10:51:27.000000000 +0200
--- gcc/cp/rtti.c 2010-10-13 15:32:11.000000000 +0200
*************** typeinfo_in_lib_p (tree type)
*** 1051,1062 ****
case BOOLEAN_TYPE:
case REAL_TYPE:
case VOID_TYPE:
return true;
case LANG_TYPE:
! if (NULLPTR_TYPE_P (type))
! return true;
! /* else fall through. */
default:
return false;
--- 1051,1061 ----
case BOOLEAN_TYPE:
case REAL_TYPE:
case VOID_TYPE:
+ case NULLPTR_TYPE:
return true;
case LANG_TYPE:
! /* fall through. */
default:
return false;
Index: gcc/dbxout.c
===================================================================
*** gcc/dbxout.c.orig 2010-10-12 11:47:28.000000000 +0200
--- gcc/dbxout.c 2010-10-13 15:35:39.000000000 +0200
*************** dbxout_type (tree type, int full)
*** 1863,1868 ****
--- 1863,1869 ----
switch (TREE_CODE (type))
{
case VOID_TYPE:
+ case NULLPTR_TYPE:
case LANG_TYPE:
/* For a void type, just define it as itself; i.e., "5=5".
This makes us consider it defined
Index: gcc/dwarf2out.c
===================================================================
*** gcc/dwarf2out.c.orig 2010-10-12 11:47:28.000000000 +0200
--- gcc/dwarf2out.c 2010-10-13 15:39:30.000000000 +0200
*************** is_base_type (tree type)
*** 12620,12625 ****
--- 12620,12626 ----
case METHOD_TYPE:
case POINTER_TYPE:
case REFERENCE_TYPE:
+ case NULLPTR_TYPE:
case OFFSET_TYPE:
case LANG_TYPE:
case VECTOR_TYPE:
*************** gen_type_die_with_usage (tree type, dw_d
*** 20224,20229 ****
--- 20225,20233 ----
/* No DIEs needed for fundamental types. */
break;
+ case NULLPTR_TYPE:
+ /* No Dwarf representation currently defined. Fallthru. */
+
case LANG_TYPE:
/* Just use DW_TAG_unspecified_type. */
{
Index: gcc/sdbout.c
===================================================================
*** gcc/sdbout.c.orig 2010-08-24 10:32:38.000000000 +0200
--- gcc/sdbout.c 2010-10-13 15:37:14.000000000 +0200
*************** plain_type_1 (tree type, int level)
*** 495,500 ****
--- 495,501 ----
switch (TREE_CODE (type))
{
case VOID_TYPE:
+ case NULLPTR_TYPE:
return T_VOID;
case BOOLEAN_TYPE:
case INTEGER_TYPE:
Index: gcc/tree.c
===================================================================
*** gcc/tree.c.orig 2010-10-11 12:11:51.000000000 +0200
--- gcc/tree.c 2010-10-13 15:39:11.000000000 +0200
*************** build_int_cst_wide (tree type, unsigned
*** 1178,1183 ****
--- 1178,1187 ----
switch (TREE_CODE (type))
{
+ case NULLPTR_TYPE:
+ gcc_assert (hi == 0 && low == 0);
+ /* Fallthru. */
+
case POINTER_TYPE:
case REFERENCE_TYPE:
/* Cache NULL pointer. */
Index: gcc/tree.def
===================================================================
*** gcc/tree.def.orig 2010-10-12 11:47:15.000000000 +0200
--- gcc/tree.def 2010-10-13 15:25:41.000000000 +0200
*************** DEFTREECODE (REAL_TYPE, "real_type", tcc
*** 162,176 ****
The TREE_TYPE points to the node for the type pointed to. */
DEFTREECODE (POINTER_TYPE, "pointer_type", tcc_type, 0)
/* _Fract and _Accum types in Embedded-C. Different fixed-point types
are distinguished by machine mode and by the TYPE_SIZE and the
TYPE_PRECISION. */
DEFTREECODE (FIXED_POINT_TYPE, "fixed_point_type", tcc_type, 0)
- /* A reference is like a pointer except that it is coerced
- automatically to the value it points to. Used in C++. */
- DEFTREECODE (REFERENCE_TYPE, "reference_type", tcc_type, 0)
-
/* The ordering of the following codes is optimized for the checking
macros in tree.h. Changing the order will degrade the speed of the
compiler. COMPLEX_TYPE, VECTOR_TYPE, ARRAY_TYPE. */
--- 162,179 ----
The TREE_TYPE points to the node for the type pointed to. */
DEFTREECODE (POINTER_TYPE, "pointer_type", tcc_type, 0)
+ /* A reference is like a pointer except that it is coerced
+ automatically to the value it points to. Used in C++. */
+ DEFTREECODE (REFERENCE_TYPE, "reference_type", tcc_type, 0)
+
+ /* The C++ decltype(nullptr) type. */
+ DEFTREECODE (NULLPTR_TYPE, "nullptr_type", tcc_type, 0)
+
/* _Fract and _Accum types in Embedded-C. Different fixed-point types
are distinguished by machine mode and by the TYPE_SIZE and the
TYPE_PRECISION. */
DEFTREECODE (FIXED_POINT_TYPE, "fixed_point_type", tcc_type, 0)
/* The ordering of the following codes is optimized for the checking
macros in tree.h. Changing the order will degrade the speed of the
compiler. COMPLEX_TYPE, VECTOR_TYPE, ARRAY_TYPE. */