OSDN Git Service

Add support for C++0x nullptr.
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 6 May 2010 20:51:52 +0000 (20:51 +0000)
committerMasaki Muranaka <monaka@monami-software.com>
Sun, 23 May 2010 05:01:48 +0000 (14:01 +0900)
gcc:
* c-common.c (c_common_reswords): Add nullptr.
* c-common.h: Add RID_NULLPTR.  Reorganize C++0x rids.
* dwarf2out.c (is_base_type): Handle NULLPTR_TYPE.
(gen_type_die_with_usage): Likewise.
* dbxout.c (dbxout_type): Likewise.
* sdbout.c (plain_type_1): Likewise.
gcc/cp:
* cp-tree.def: Add NULLPTR_TYPE.
* cp-tree.h: Add nullptr_node.
(cp_tree_index): Add CPTI_NULLPTR.
(SCALAR_TYPE_P): Add NULLPTR_TYPE.
* call.c (null_ptr_cst_p): Handle nullptr.
(standard_conversion): Likewise.
(convert_arg_to_ellipsis): Likewise.
* mangle.c (write_type): Likewise.
* name-lookup.c (arg_assoc_type): Likewise.
* parser.c (cp_parser_primary_expression): Likewise.
* typeck.c (cp_build_binary_op): Likewise.
(build_reinterpret_cast_1): Likewise.
* error.c (dump_type): Likewise.
(dump_type_prefix, dump_type_suffix): Likewise.
* decl.c (cxx_init_decl_processing): Likewise.
* cxx-pretty-print.c (pp_cxx_constant): Likewise.
* cvt.c (ocp_convert): Likewise.
* rtti.c (typeinfo_in_lib_p, emit_support_tinfos): Put
nullptr_t tinfo in libsupc++.
libstdc++-v3:
* config/abi/pre/gnu.ver: Add typeinfo for decltype(nullptr).
libiberty:
* cp-demangle.c (cplus_demangle_builtin_types): Add nullptr.
(cplus_demangle_type): Handle nullptr.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@159131 138bc75d-0d04-0410-961f-82ee72b054a4

25 files changed:
gcc/ChangeLog
gcc/c-common.c
gcc/c-common.h
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.def
gcc/cp/cp-tree.h
gcc/cp/cvt.c
gcc/cp/cxx-pretty-print.c
gcc/cp/decl.c
gcc/cp/error.c
gcc/cp/mangle.c
gcc/cp/name-lookup.c
gcc/cp/rtti.c
gcc/cp/typeck.c
gcc/dbxout.c
gcc/dwarf2out.c
gcc/fortran/trans-expr.c
gcc/sdbout.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/nullptr15.C
gcc/testsuite/g++.dg/cpp0x/nullptr20.C
libiberty/ChangeLog
libstdc++-v3/ChangeLog
libstdc++-v3/config/abi/pre/gnu.ver

index a625399..94305fa 100644 (file)
@@ -1,3 +1,13 @@
+2010-05-06  Magnus Fromreide  <magfr@lysator.liu.se>
+           Jason Merrill  <jason@redhat.com>
+
+       * c-common.c (c_common_reswords): Add nullptr.
+       * c-common.h: Add RID_NULLPTR.  Reorganize C++0x rids.
+       * dwarf2out.c (is_base_type): Handle NULLPTR_TYPE.
+       (gen_type_die_with_usage): Likewise.
+       * dbxout.c (dbxout_type): Likewise.
+       * sdbout.c (plain_type_1): Likewise.
+
 2010-05-06  Jason Merrill  <jason@redhat.com>
 
        * gimplify.c (gimplify_expr): Set GS_ALL_DONE when appropriate.
index d939e12..e11b6af 100644 (file)
@@ -656,6 +656,7 @@ const struct c_common_resword c_common_reswords[] =
   { "mutable",         RID_MUTABLE,    D_CXXONLY | D_CXXWARN },
   { "namespace",       RID_NAMESPACE,  D_CXXONLY | D_CXXWARN },
   { "new",             RID_NEW,        D_CXXONLY | D_CXXWARN },
+  { "nullptr",         RID_NULLPTR,    D_CXXONLY | D_CXX0X | D_CXXWARN },
   { "operator",                RID_OPERATOR,   D_CXXONLY | D_CXXWARN },
   { "private",         RID_PRIVATE,    D_CXX_OBJC | D_CXXWARN },
   { "protected",       RID_PROTECTED,  D_CXX_OBJC | D_CXXWARN },
index 0da83d5..e32fa39 100644 (file)
@@ -114,7 +114,7 @@ enum rid
   RID_IS_UNION,
 
   /* C++0x */
-  RID_STATIC_ASSERT, RID_CONSTEXPR, RID_DECLTYPE,
+  RID_CONSTEXPR, RID_DECLTYPE, RID_NULLPTR, RID_STATIC_ASSERT,
 
   /* Objective-C */
   RID_AT_ENCODE,   RID_AT_END,
@@ -155,8 +155,8 @@ enum rid
   RID_FIRST_MODIFIER = RID_STATIC,
   RID_LAST_MODIFIER = RID_ONEWAY,
 
-  RID_FIRST_CXX0X = RID_STATIC_ASSERT,
-  RID_LAST_CXX0X = RID_DECLTYPE,
+  RID_FIRST_CXX0X = RID_CONSTEXPR,
+  RID_LAST_CXX0X = RID_STATIC_ASSERT,
   RID_FIRST_AT = RID_AT_ENCODE,
   RID_LAST_AT = RID_AT_IMPLEMENTATION,
   RID_FIRST_PQ = RID_IN,
index a5a7afa..860f4e7 100644 (file)
@@ -1,3 +1,27 @@
+2010-05-06  Magnus Fromreide  <magfr@lysator.liu.se>
+           Jason Merrill  <jason@redhat.com>
+
+       Add support for C++0x nullptr.
+       * cp-tree.def: Add NULLPTR_TYPE.
+       * cp-tree.h: Add nullptr_node.
+       (cp_tree_index): Add CPTI_NULLPTR.
+       (SCALAR_TYPE_P): Add NULLPTR_TYPE.
+       * call.c (null_ptr_cst_p): Handle nullptr.
+       (standard_conversion): Likewise.
+       (convert_arg_to_ellipsis): Likewise.
+       * mangle.c (write_type): Likewise.
+       * name-lookup.c (arg_assoc_type): Likewise.
+       * parser.c (cp_parser_primary_expression): Likewise.
+       * typeck.c (cp_build_binary_op): Likewise.
+       (build_reinterpret_cast_1): Likewise.
+       * error.c (dump_type): Likewise.
+       (dump_type_prefix, dump_type_suffix): Likewise.
+       * decl.c (cxx_init_decl_processing): Likewise.
+       * cxx-pretty-print.c (pp_cxx_constant): Likewise.
+       * cvt.c (ocp_convert): Likewise.
+       * rtti.c (typeinfo_in_lib_p, emit_support_tinfos): Put
+       nullptr_t tinfo in libsupc++.
+
 2010-05-06  Jason Merrill  <jason@redhat.com>
 
        * semantics.c (simplify_aggr_init_expr): Use INIT_EXPR.
index e8fcc94..d74eb19 100644 (file)
@@ -460,9 +460,11 @@ null_ptr_cst_p (tree t)
   /* [conv.ptr]
 
      A null pointer constant is an integral constant expression
-     (_expr.const_) rvalue of integer type that evaluates to zero.  */
+     (_expr.const_) rvalue of integer type that evaluates to zero or
+     an rvalue of type std::nullptr_t. */
   t = integral_constant_value (t);
-  if (t == null_node)
+  if (t == null_node
+      || TREE_CODE (TREE_TYPE (t)) == NULLPTR_TYPE)
     return true;
   if (CP_INTEGRAL_TYPE_P (TREE_TYPE (t)) && integer_zerop (t))
     {
@@ -776,7 +778,12 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
   if (same_type_p (from, to))
     return conv;
 
-  if ((tcode == POINTER_TYPE || TYPE_PTR_TO_MEMBER_P (to))
+  /* [conv.ptr]
+     A null pointer constant can be converted to a pointer type; ... A
+     null pointer constant of integral type can be converted to an
+     rvalue of type std::nullptr_t. */
+  if ((tcode == POINTER_TYPE || TYPE_PTR_TO_MEMBER_P (to)
+       || tcode == NULLPTR_TYPE)
       && expr && null_ptr_cst_p (expr))
     conv = build_conv (ck_std, to, conv);
   else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE)
@@ -911,17 +918,20 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
 
          An rvalue of arithmetic, unscoped enumeration, pointer, or
          pointer to member type can be converted to an rvalue of type
-         bool.  */
+         bool. ... An rvalue of type std::nullptr_t can be converted
+         to an rvalue of type bool;  */
       if (ARITHMETIC_TYPE_P (from)
          || UNSCOPED_ENUM_P (from)
          || fcode == POINTER_TYPE
-         || TYPE_PTR_TO_MEMBER_P (from))
+         || TYPE_PTR_TO_MEMBER_P (from)
+         || fcode == NULLPTR_TYPE)
        {
          conv = build_conv (ck_std, to, conv);
          if (fcode == POINTER_TYPE
              || TYPE_PTRMEM_P (from)
              || (TYPE_PTRMEMFUNC_P (from)
-                 && conv->rank < cr_pbool))
+                 && conv->rank < cr_pbool)
+              || fcode == NULLPTR_TYPE)
            conv->rank = cr_pbool;
          return conv;
        }
@@ -5192,6 +5202,8 @@ convert_arg_to_ellipsis (tree arg)
          < TYPE_PRECISION (double_type_node))
       && !DECIMAL_FLOAT_MODE_P (TYPE_MODE (TREE_TYPE (arg))))
     arg = convert_to_real (double_type_node, arg);
+  else if (TREE_CODE (TREE_TYPE (arg)) == NULLPTR_TYPE)
+    arg = null_pointer_node;
   else if (INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (arg)))
     arg = perform_integral_promotions (arg);
 
@@ -6788,9 +6800,8 @@ compare_ics (conversion *ics1, conversion *ics2)
     Two conversion sequences with the same rank are indistinguishable
     unless one of the following rules applies:
 
-    --A conversion that is not a conversion of a pointer, or pointer
-      to member, to bool is better than another conversion that is such
-      a conversion.
+    --A conversion that does not a convert a pointer, pointer to member,
+      or std::nullptr_t to bool is better than one that does.
 
     The ICS_STD_RANK automatically handles the pointer-to-bool rule,
     so that we do not have to check it explicitly.  */
index c71f94c..c3e8208 100644 (file)
@@ -449,6 +449,9 @@ DEFTREECODE (DECLTYPE_TYPE, "decltype_type", tcc_type, 0)
    instantiation time.  */
 DEFTREECODE (TEMPLATE_INFO, "template_info", tcc_exceptional, 0)
 
+/* The type of a nullptr expression. This is a C++0x extension. */
+DEFTREECODE (NULLPTR_TYPE, "decltype(nullptr)", tcc_type, 0)
+
 /*
 Local variables:
 mode:c
index 4fca633..22a7487 100644 (file)
@@ -775,6 +775,8 @@ enum cp_tree_index
 
     CPTI_KEYED_CLASSES,
 
+    CPTI_NULLPTR,
+
     CPTI_MAX
 };
 
@@ -809,6 +811,7 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
 #define abort_fndecl                   cp_global_trees[CPTI_ABORT_FNDECL]
 #define global_delete_fndecl           cp_global_trees[CPTI_GLOBAL_DELETE_FNDECL]
 #define current_aggr                   cp_global_trees[CPTI_AGGR_TAG]
+#define nullptr_node                   cp_global_trees[CPTI_NULLPTR]
 
 /* We cache these tree nodes so as to call get_identifier less
    frequently.  */
@@ -3001,8 +3004,9 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
 
 /* [basic.types]
 
-   Arithmetic types, enumeration types, pointer types, and
-   pointer-to-member types, are collectively called scalar types.
+   Arithmetic types, enumeration types, pointer types,
+   pointer-to-member types, and std::nullptr_t are collectively called
+   scalar types.
    
    Keep these checks in ascending code order.  */
 #define SCALAR_TYPE_P(TYPE)                    \
@@ -3010,7 +3014,8 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
    || TREE_CODE (TYPE) == ENUMERAL_TYPE                \
    || ARITHMETIC_TYPE_P (TYPE)                 \
    || TYPE_PTR_P (TYPE)                                \
-   || TYPE_PTRMEMFUNC_P (TYPE))
+   || TYPE_PTRMEMFUNC_P (TYPE)                  \
+   || TREE_CODE (TYPE) == NULLPTR_TYPE)
 
 /* Determines whether this type is a C++0x scoped enumeration
    type. Scoped enumerations types are introduced via "enum class" or
index 646610a..b357084 100644 (file)
@@ -1,6 +1,6 @@
 /* Language-level data type conversion for GNU C++.
    Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
    Free Software Foundation, Inc.
    Hacked by Michael Tiemann (tiemann@cygnus.com)
 
@@ -704,7 +704,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
 
       return fold_if_not_in_template (convert_to_integer (type, e));
     }
-  if (NULLPTR_TYPE_P (type) && e && null_ptr_cst_p (e))
+  if (code == NULLPTR_TYPE && e && null_ptr_cst_p (e))
     return nullptr_node;
   if (POINTER_TYPE_P (type) || TYPE_PTR_TO_MEMBER_P (type))
     return fold_if_not_in_template (cp_convert_to_pointer (type, e));
@@ -822,23 +822,9 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
 tree
 convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain)
 {
-  tree exprv;
-
   if (expr == error_mark_node
       || TREE_TYPE (expr) == error_mark_node)
     return error_mark_node;
-
-  exprv = expr;
-  while (TREE_CODE (exprv) == COMPOUND_EXPR)
-    exprv = TREE_OPERAND (exprv, 1);
-  if (DECL_P (exprv) || handled_component_p (exprv))
-    /* Expr is not being 'used' here, otherwise we whould have
-       called mark_{rl}value_use use here, which would have in turn
-       called mark_exp_read.  Rather, we call mark_exp_read directly
-       to avoid some warnings when
-       -Wunused-but-set-{variable,parameter} is in effect.  */
-    mark_exp_read (exprv);
-
   if (!TREE_TYPE (expr))
     return expr;
   if (invalid_nonstatic_memfn_p (expr, complain))
index 04a8314..55def21 100644 (file)
@@ -1,6 +1,6 @@
 /* Implementation of subroutines for the GNU C++ pretty-printer.
    Copyright (C) 2003, 2004, 2005, 2007, 2008,
-   2009, 2010 Free Software Foundation, Inc.
+   2009 Free Software Foundation, Inc.
    Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
 
 This file is part of GCC.
@@ -23,10 +23,10 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
+#include "real.h"
 #include "intl.h"
-#include "cp-tree.h"
 #include "cxx-pretty-print.h"
-#include "tree-pretty-print.h"
+#include "cp-tree.h"
 #include "toplev.h"
 
 /* Translate if being used for diagnostics, but not for dump files or
@@ -340,7 +340,7 @@ pp_cxx_constant (cxx_pretty_printer *pp, tree t)
       break;
 
     case INTEGER_CST:
-      if (NULLPTR_TYPE_P (TREE_TYPE (t)))
+      if (TREE_CODE (TREE_TYPE (t)) == NULLPTR_TYPE)
        {
          pp_string (pp, "nullptr");
          break;
index f9114a9..70b1041 100644 (file)
@@ -3526,6 +3526,17 @@ cxx_init_decl_processing (void)
     push_cp_library_fn (VEC_NEW_EXPR, newtype);
     global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype);
     push_cp_library_fn (VEC_DELETE_EXPR, deltype);
+
+    {
+      tree 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);
+      nullptr_node = make_node (INTEGER_CST);
+      TREE_TYPE (nullptr_node) = nullptr_type_node;
+    }
   }
 
   abort_fndecl
index dcdfe89..28c45f2 100644 (file)
@@ -481,6 +481,10 @@ dump_type (tree t, int flags)
       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.  */
@@ -709,6 +713,7 @@ dump_type_prefix (tree t, int flags)
     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;
@@ -811,6 +816,7 @@ dump_type_suffix (tree t, int flags)
     case DECLTYPE_TYPE:
     case TYPE_PACK_EXPANSION:
     case FIXED_POINT_TYPE:
+    case NULLPTR_TYPE:
       break;
 
     default:
index 89ccbaf..b160744 100644 (file)
@@ -1932,6 +1932,10 @@ write_type (tree type)
               write_char ('E');
               break;
 
+           case NULLPTR_TYPE:
+              write_string ("Dn");
+              break;
+
            case TYPEOF_TYPE:
              sorry ("mangling typeof, use decltype instead");
              break;
index 405bf16..465e711 100644 (file)
@@ -4879,6 +4879,7 @@ arg_assoc_type (struct arg_lookup *k, tree type)
     case BOOLEAN_TYPE:
     case FIXED_POINT_TYPE:
     case DECLTYPE_TYPE:
+    case NULLPTR_TYPE:
       return false;
     case RECORD_TYPE:
       if (TYPE_PTRMEMFUNC_P (type))
index 9d300d7..9a7faec 100644 (file)
@@ -155,7 +155,7 @@ init_rtti_processing (void)
                             /*tag_scope=*/ts_current, false);
   pop_namespace ();
   const_type_info_type_node
-    = cp_build_qualified_type (type_info_type, TYPE_QUAL_CONST);
+    = build_qualified_type (type_info_type, TYPE_QUAL_CONST);
   type_info_ptr_type = build_pointer_type (const_type_info_type_node);
 
   unemitted_tinfo_decls = VEC_alloc (tree, gc, 124);
@@ -192,8 +192,8 @@ build_headof (tree exp)
                                                   tf_warning_or_error), 
                            index);
 
-  type = cp_build_qualified_type (ptr_type_node,
-                                 cp_type_quals (TREE_TYPE (exp)));
+  type = build_qualified_type (ptr_type_node,
+                              cp_type_quals (TREE_TYPE (exp)));
   return build2 (POINTER_PLUS_EXPR, type, exp,
                 convert_to_integer (sizetype, offset));
 }
@@ -255,8 +255,7 @@ get_tinfo_decl_dynamic (tree exp)
   type = TYPE_MAIN_VARIANT (type);
 
   /* For UNKNOWN_TYPEs call complete_type_or_else to get diagnostics.  */
-  if (CLASS_TYPE_P (type) || type == unknown_type_node
-      || type == init_list_type_node)
+  if (CLASS_TYPE_P (type) || TREE_CODE (type) == UNKNOWN_TYPE)
     type = complete_type_or_else (type, exp);
 
   if (!type)
@@ -483,8 +482,7 @@ get_typeid (tree type)
   type = TYPE_MAIN_VARIANT (type);
 
   /* For UNKNOWN_TYPEs call complete_type_or_else to get diagnostics.  */
-  if (CLASS_TYPE_P (type) || type == unknown_type_node
-      || type == init_list_type_node)
+  if (CLASS_TYPE_P (type) || TREE_CODE (type) == UNKNOWN_TYPE)
     type = complete_type_or_else (type, NULL_TREE);
 
   if (!type)
@@ -726,7 +724,7 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
                                    /*tag_scope=*/ts_current, false);
 
              tinfo_ptr = build_pointer_type
-               (cp_build_qualified_type
+               (build_qualified_type
                 (tinfo_ptr, TYPE_QUAL_CONST));
              name = "__dynamic_cast";
              tmp = tree_cons
@@ -871,7 +869,7 @@ tinfo_base_init (tinfo_s *ti, tree target)
 
     /* Generate the NTBS array variable.  */
     tree name_type = build_cplus_array_type
-                    (cp_build_qualified_type (char_type_node, TYPE_QUAL_CONST),
+                    (build_qualified_type (char_type_node, TYPE_QUAL_CONST),
                     NULL_TREE);
 
     /* Determine the name of the variable -- and remember with which
@@ -1046,13 +1044,9 @@ typeinfo_in_lib_p (tree type)
     case BOOLEAN_TYPE:
     case REAL_TYPE:
     case VOID_TYPE:
+    case NULLPTR_TYPE:
       return true;
 
-    case LANG_TYPE:
-      if (NULLPTR_TYPE_P (type))
-       return true;
-      /* else fall through.  */
-
     default:
       return false;
     }
@@ -1458,6 +1452,7 @@ emit_support_tinfos (void)
 {
   /* Dummy static variable so we can put nullptr in the array; it will be
      set before we actually start to walk the array.  */
+  static tree nullptr_type_node;
   static tree *const fundamentals[] =
   {
     &void_type_node,
@@ -1487,6 +1482,7 @@ emit_support_tinfos (void)
   if (!dtor || DECL_EXTERNAL (dtor))
     return;
   doing_runtime = 1;
+  nullptr_type_node = TREE_TYPE (nullptr_node);
   for (ix = 0; fundamentals[ix]; ix++)
     {
       tree bltn = *fundamentals[ix];
@@ -1495,8 +1491,8 @@ emit_support_tinfos (void)
 
       types[0] = bltn;
       types[1] = build_pointer_type (bltn);
-      types[2] = build_pointer_type (cp_build_qualified_type (bltn,
-                                                             TYPE_QUAL_CONST));
+      types[2] = build_pointer_type (build_qualified_type (bltn,
+                                                          TYPE_QUAL_CONST));
 
       for (i = 0; i < 3; ++i)
        {
index c601539..61d5f22 100644 (file)
@@ -3993,6 +3993,9 @@ cp_build_binary_op (location_t location,
            }
          result_type = type1;
        }
+      else if (null_ptr_cst_p (op0) && null_ptr_cst_p (op1))
+       /* One of the operands must be of nullptr_t type.  */
+        result_type = TREE_TYPE (nullptr_node);
       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
        {
          result_type = type0;
@@ -4192,12 +4195,13 @@ cp_build_binary_op (location_t location,
       else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE)
        result_type = composite_pointer_type (type0, type1, op0, op1,
                                              CPO_COMPARISON, complain);
-      else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST
-              && integer_zerop (op1))
+      else if (code0 == POINTER_TYPE && null_ptr_cst_p (op1))
        result_type = type0;
-      else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST
-              && integer_zerop (op0))
+      else if (code1 == POINTER_TYPE && null_ptr_cst_p (op0))
        result_type = type1;
+      else if (null_ptr_cst_p (op0) && null_ptr_cst_p (op1))
+       /* One of the operands must be of nullptr_t type.  */
+        result_type = TREE_TYPE (nullptr_node);
       else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
        {
          result_type = type0;
@@ -6020,8 +6024,11 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
 
   /* [expr.reinterpret.cast]
      A pointer can be converted to any integral type large enough to
-     hold it.  */
-  if (CP_INTEGRAL_TYPE_P (type) && TYPE_PTR_P (intype))
+     hold it. ... A value of type std::nullptr_t can be converted to
+     an integral type; the conversion has the same meaning and
+     validity as a conversion of (void*)0 to the integral type.  */
+  if (CP_INTEGRAL_TYPE_P (type)
+      && (TYPE_PTR_P (intype) || TREE_CODE (intype) == NULLPTR_TYPE))
     {
       if (TYPE_PRECISION (type) < TYPE_PRECISION (intype))
         {
@@ -6031,6 +6038,8 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p,
           else
             return error_mark_node;
         }
+      if (TREE_CODE (intype) == NULLPTR_TYPE)
+        return build_int_cst (type, 0);
     }
   /* [expr.reinterpret.cast]
      A value of integral or enumeration type can be explicitly
index a314e7b..bce5703 100644 (file)
@@ -1867,6 +1867,7 @@ dbxout_type (tree type, int full)
     {
     case VOID_TYPE:
     case LANG_TYPE:
+    case NULLPTR_TYPE:
       /* For a void type, just define it as itself; i.e., "5=5".
         This makes us consider it defined
         without saying what it is.  The debugger will make it
index 416f75a..66ac5eb 100644 (file)
@@ -12108,6 +12108,7 @@ is_base_type (tree type)
     case ENUMERAL_TYPE:
     case FUNCTION_TYPE:
     case METHOD_TYPE:
+    case NULLPTR_TYPE:
     case POINTER_TYPE:
     case REFERENCE_TYPE:
     case OFFSET_TYPE:
@@ -19171,6 +19172,18 @@ gen_type_die_with_usage (tree type, dw_die_ref context_die,
         when appropriate.  */
       return;
 
+    case NULLPTR_TYPE:
+      {
+        dw_die_ref type_die = lookup_type_die (type);
+        if (type_die == NULL)
+          {
+            type_die = new_die (DW_TAG_unspecified_type, comp_unit_die, type);
+            add_name_attribute (type_die, "decltype(nullptr)");
+            equate_type_number_to_die (type, type_die);
+          }
+      }
+      return;
+
     case VOID_TYPE:
     case INTEGER_TYPE:
     case REAL_TYPE:
index dfd38cc..47883e2 100644 (file)
@@ -3077,7 +3077,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
                 it is invalid to pass a non-present argument on, even
                 though there is no technical reason for this in gfortran.
                 See Fortran 2003, Section 12.4.1.6 item (7)+(8).  */
-             tree present, nullptr, type;
+             tree present, null_ptr, type;
 
              if (attr->allocatable
                  && (fsym == NULL || !fsym->attr.allocatable))
@@ -3101,10 +3101,10 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
              present = fold_build2 (EQ_EXPR, boolean_type_node, present,
                                     fold_convert (type, null_pointer_node));
              type = TREE_TYPE (parmse.expr);
-             nullptr = fold_build2 (EQ_EXPR, boolean_type_node, parmse.expr,
-                                    fold_convert (type, null_pointer_node));
+             null_ptr = fold_build2 (EQ_EXPR, boolean_type_node, parmse.expr,
+                                     fold_convert (type, null_pointer_node));
              cond = fold_build2 (TRUTH_ORIF_EXPR, boolean_type_node,
-                                 present, nullptr);
+                                 present, null_ptr);
            }
           else
            {
index 87a00b4..6a771f4 100644 (file)
@@ -493,6 +493,7 @@ plain_type_1 (tree type, int level)
   switch (TREE_CODE (type))
     {
     case VOID_TYPE:
+    case NULLPTR_TYPE:
       return T_VOID;
     case BOOLEAN_TYPE:
     case INTEGER_TYPE:
index 21fec66..8375faf 100644 (file)
@@ -1,3 +1,31 @@
+2010-05-06  Magnus Fromreide  <magfr@lysator.liu.se>
+           Jason Merrill  <jason@redhat.com>
+
+       * g++.dg/cpp0x/nullptr01.C: New.
+       * g++.dg/cpp0x/nullptr02.C: New.
+       * g++.dg/cpp0x/nullptr03.C: New.
+       * g++.dg/cpp0x/nullptr04.C: New.
+       * g++.dg/cpp0x/nullptr05.C: New.
+       * g++.dg/cpp0x/nullptr06.C: New.
+       * g++.dg/cpp0x/nullptr07.C: New.
+       * g++.dg/cpp0x/nullptr08.C: New.
+       * g++.dg/cpp0x/nullptr09.C: New.
+       * g++.dg/cpp0x/nullptr10.C: New.
+       * g++.dg/cpp0x/nullptr11.C: New.
+       * g++.dg/cpp0x/nullptr12.C: New.
+       * g++.dg/cpp0x/nullptr13.C: New.
+       * g++.dg/cpp0x/nullptr14.C: New.
+       * g++.dg/cpp0x/nullptr15.C: New.
+       * g++.dg/cpp0x/nullptr16.C: New.
+       * g++.dg/cpp0x/nullptr17.C: New.
+       * g++.dg/cpp0x/nullptr18.C: New.
+       * g++.dg/cpp0x/nullptr19.C: New.
+       * g++.dg/cpp0x/nullptr20.C: New.
+       * g++.dg/cpp0x/nullptr21.C: New.
+       * g++.dg/cpp0x/nullptr22.C: New.
+       * g++.dg/debug/nullptr01.C: New.
+       * gcc.dg/Wcxx-compat-2.c: Test nullptr and constexpr.
+
 2010-05-06  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/40406
index abb45f4..4572c53 100644 (file)
@@ -10,7 +10,7 @@ template <typename T, typename U>
 inline typename tType_equal<T, U>::type
 type_equal(U) { }
 
-template<typename T> T* g( T* t ); // { dg-message "candidate" }
+template<typename T> T* g( T* t );
 
 void test_g()
 {
index a959b00..b7457ca 100644 (file)
@@ -11,7 +11,7 @@ int main()
   char buf1[64];
   char buf2[64];
 
-  std::sprintf(buf1, "%p", (void*)0);
-  std::sprintf(buf2, "%p", nullptr);
+  std::snprintf(buf1, sizeof(buf1), "%p", (void*)0);
+  std::snprintf(buf2, sizeof(buf2), "%p", nullptr);
   return std::strcmp(buf1, buf2) != 0;
 }
index cf4cdc4..4414e04 100644 (file)
@@ -1,3 +1,10 @@
+2010-05-06  Magnus Fromreide  <magfr@lysator.liu.se>
+           Jason Merrill  <jason@redhat.com>
+
+       * cp-demangle.c (cplus_demangle_builtin_types): Add nullptr.
+       (cplus_demangle_type): Handle nullptr.
+       * testsuite/demangle-expected: Test it.
+
 2010-04-23  Pedro Alves  <pedro@codesourcery.com>
 
        * lbasename.c (lbasename): Split into ...
index 0e284ec..fe4b74a 100644 (file)
@@ -1,3 +1,7 @@
+2010-05-06  Jason Merrill  <jason@redhat.com>
+
+       * config/abi/pre/gnu.ver: Add typeinfo for decltype(nullptr).
+
 2010-05-06  Jonathan Wakely  <jwakely.gcc@gmail.com>
 
        * include/bits/basic_string.h: Escape class names in doxygen docs.
index 998b651..3552d59 100644 (file)
@@ -1307,18 +1307,9 @@ CXXABI_1.3.3 {
 
 CXXABI_1.3.4 {
 
-    # typeinfo for decimal floating point types
-    _ZTID[fde];
-    _ZTIPD[fde];
-    _ZTIPKD[fde];
+    # typeinfo for decimal floating point types and decltype(nullptr)
+    _ZTID[fden];
+    _ZTIPD[fden];
+    _ZTIPKD[fden];
 
 } CXXABI_1.3.3;
-
-CXXABI_1.3.5 {
-
-    # typeinfo for decltype(nullptr)
-    _ZTIDn;
-    _ZTIPDn;
-    _ZTIPKDn;
-
-} CXXABI_1.3.4;