On Sat, May 17, 2014 at 10:15 AM, Richard Sandiford
<rdsandif...@googlemail.com> wrote:
> The main thing keeping zero-precision wide-ints alive was void_zero_node,
> a tree used in the C and C++ frontends that has type VOID_TYPE but code
> INTEGER_CST.
>
> Richard B. asked me to replace the INTEGER_CST with a new constant type,
> here called VOID_CST.  Most of it is straight-forward.  The one perhaps
> controversial bit is that C++ uses void_(zero_)node to represent dummy
> objects when e.g. taking the address of a member function without an
> associated object.  IIUC the node used in this situation needs to be
> distinct from anything that could occur in user code and therefore couldn't
> be a simple null pointer.
>
> This reaches the gimplifier in cases like
> g++.old-deja/g++.brendan/operators4.C.  I chose to handle it in the
> gimplifier, since void_zero_node was previously handled there too,
> although perhaps by accident.  If you object strongly to this then
> I'll need pretty detailed instructions about what to do instead,
> i.e. exactly which parts of the C++ front end need to be changed
> in order for dummy objects never to escape.

I suppose it reaches the gimplifier because it's not handled in
fold-const.c:fold_convert_loc while the INTEGER_CST void_zero_node
was (through fold_convert_const).

That said, only handling (T)void_cst in gimplification looks like
a hack.  If necessary we'd want to treat it as construct-T-with-zero-value
consistently.

> I wasn't sure if any errors could ever print void_(zero_)node,
> so I tested the pretty-printing routines by adding fake errors
> after convert_to_void, etc.
>
> Tested on x86_64-linux-gnu.  OK to install?
>
> I haven't yet tested whether this makes zero precision go away completely,
> but will do soon.

The middle-end changes look good to me, but as this mainly affects
the C++ frontend I'd like a C++ maintainer to chime in.

Thanks,
Richard.

> Thanks,
> Richard
>
>
> gcc/
>         * tree.def (VOID_CST): New.
>         * tree-core.h (TI_VOID): New.
>         * tree.h (void_node): New.
>         * tree.c (tree_node_structure_for_code, tree_code_size)
>         (iterative_hash_expr): Handle VOID_CST.
>         (build_common_tree_nodes): Initialize void_node.
>         * gimplify.c (gimplify_conversion): Handle void_node.
>
> gcc/c-family/
>         * c-common.h (CTI_VOID_ZERO, void_zero_node): Delete.
>         * c-common.c (c_common_nodes_and_builtins): Don't initialize
>         void_zero_node.
>         * c-pretty-print.c (pp_c_void_constant): New function.
>         (c_pretty_printer::constant, c_pretty_printer::primary_expression)
>         (c_pretty_printer::expression): Handle VOID_CST.
>         * cilk.c (extract_free_variables): Likewise.
>         * c-ubsan.c (ubsan_instrument_division, ubsan_instrument_shift)
>         (ubsan_instrument_vla): Use void_node instead of void_zero_node.
>
> gcc/c/
>         * c-array-notation.c (expand_array_notations): Use void_node
>         instead of void_zero_node.
>
> gcc/cp/
>         * cvt.c (convert_to_void): Use void_node instead of void_zero_node.
>         * cp-array-notation.c (replace_invariant_exprs): Likewise.
>         (expand_array_notation): Handle VOID_CST.
>         * error.c (dump_expr): Likewise.
>         * cxx-pretty-print.c (cxx_pretty_printer::primary_expression)
>         (cxx_pretty_printer::expression): Likewise.
>         (pp_cxx_new_expression): Use void_node instead of void_zero_node.
>         * decl.c (register_dtor_fn): Likewise.
>         * init.c (build_raw_new_expr, build_new_1, build_vec_init)
>         (build_delete, push_base_cleanups): Likewise.
>         * mangle.c (write_expression): Likewise.
>         * semantics.c (finish_break_stmt, empty_expr_stmt_p): Likewise.
>         * pt.c (tsubst_decl, tsubst_copy_and_build): Likewise.
>         (tsubst, tsubst_copy, build_non_dependent_expr): Handle VOID_CST.
>         * tree.c (cp_tree_equal): Likewise.
>         (build_dummy_object, is_dummy_object, stabilize_expr): Use void_node
>         instead of void_zero_node.
>         * typeck.c (check_return_expr): Likewise.
>         * typeck2.c (build_functional_cast): Likewise.
>
> Index: gcc/tree.def
> ===================================================================
> --- gcc/tree.def        2014-05-06 18:39:10.534452560 +0100
> +++ gcc/tree.def        2014-05-17 08:49:49.457516579 +0100
> @@ -257,6 +257,8 @@ DEFTREECODE (LANG_TYPE, "lang_type", tcc
>
>  /* First, the constants.  */
>
> +DEFTREECODE (VOID_CST, "void_cst", tcc_constant, 0)
> +
>  /* Contents are in an array of HOST_WIDE_INTs.
>
>     We often access these constants both in their native precision and
> Index: gcc/tree-core.h
> ===================================================================
> --- gcc/tree-core.h     2014-05-06 18:39:14.152493199 +0100
> +++ gcc/tree-core.h     2014-05-17 08:49:49.457516579 +0100
> @@ -410,6 +410,8 @@ enum tree_index {
>    TI_UINT32_TYPE,
>    TI_UINT64_TYPE,
>
> +  TI_VOID,
> +
>    TI_INTEGER_ZERO,
>    TI_INTEGER_ONE,
>    TI_INTEGER_THREE,
> Index: gcc/tree.h
> ===================================================================
> --- gcc/tree.h  2014-05-13 07:54:45.416524663 +0100
> +++ gcc/tree.h  2014-05-17 08:49:49.458516588 +0100
> @@ -3245,6 +3245,8 @@ #define uint16_type_node          global_trees[T
>  #define uint32_type_node               global_trees[TI_UINT32_TYPE]
>  #define uint64_type_node               global_trees[TI_UINT64_TYPE]
>
> +#define void_node                      global_trees[TI_VOID]
> +
>  #define integer_zero_node              global_trees[TI_INTEGER_ZERO]
>  #define integer_one_node               global_trees[TI_INTEGER_ONE]
>  #define integer_three_node              global_trees[TI_INTEGER_THREE]
> Index: gcc/tree.c
> ===================================================================
> --- gcc/tree.c  2014-05-13 07:54:45.415524654 +0100
> +++ gcc/tree.c  2014-05-17 08:49:49.460516606 +0100
> @@ -383,6 +383,7 @@ tree_node_structure_for_code (enum tree_
>    switch (code)
>      {
>        /* tcc_constant cases.  */
> +    case VOID_CST:             return TS_TYPED;
>      case INTEGER_CST:          return TS_INT_CST;
>      case REAL_CST:             return TS_REAL_CST;
>      case FIXED_CST:            return TS_FIXED_CST;
> @@ -652,6 +653,7 @@ tree_code_size (enum tree_code code)
>      case tcc_constant:  /* a constant */
>        switch (code)
>         {
> +       case VOID_CST:          return sizeof (struct tree_typed);
>         case INTEGER_CST:       gcc_unreachable ();
>         case REAL_CST:          return sizeof (struct tree_real_cst);
>         case FIXED_CST:         return sizeof (struct tree_fixed_cst);
> @@ -7360,6 +7362,8 @@ iterative_hash_expr (const_tree t, hashv
>      {
>      /* Alas, constants aren't shared, so we can't rely on pointer
>         identity.  */
> +    case VOID_CST:
> +      return iterative_hash_hashval_t (0, val);
>      case INTEGER_CST:
>        for (i = 0; i < TREE_INT_CST_NUNITS (t); i++)
>         val = iterative_hash_host_wide_int (TREE_INT_CST_ELT (t, i), val);
> @@ -9631,6 +9635,9 @@ build_common_tree_nodes (bool signed_cha
>    TYPE_ALIGN (void_type_node) = BITS_PER_UNIT;
>    TYPE_USER_ALIGN (void_type_node) = 0;
>
> +  void_node = make_node (VOID_CST);
> +  TREE_TYPE (void_node) = void_type_node;
> +
>    null_pointer_node = build_int_cst (build_pointer_type (void_type_node), 0);
>    layout_type (TREE_TYPE (null_pointer_node));
>
> Index: gcc/gimplify.c
> ===================================================================
> --- gcc/gimplify.c      2014-05-13 07:54:48.140550695 +0100
> +++ gcc/gimplify.c      2014-05-17 08:49:49.475516741 +0100
> @@ -1681,7 +1681,15 @@ gimplify_conversion (tree *expr_p)
>    /* Then strip away all but the outermost conversion.  */
>    STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
>
> -  /* And remove the outermost conversion if it's useless.  */
> +  /* Support C++-style dummy objects, in which void_zero is
> +     cast to a pointer type.  We treat these as null pointers.  */
> +  if (TREE_OPERAND (*expr_p, 0) == void_node)
> +    {
> +      gcc_checking_assert (POINTER_TYPE_P (TREE_TYPE (*expr_p)));
> +      *expr_p = build_int_cst (TREE_TYPE (*expr_p), 0);
> +    }
> +
> +  /* Remove the outermost conversion if it's useless.  */
>    if (tree_ssa_useless_type_conversion (*expr_p))
>      *expr_p = TREE_OPERAND (*expr_p, 0);
>
> Index: gcc/c-family/c-common.h
> ===================================================================
> --- gcc/c-family/c-common.h     2014-05-08 21:24:01.274683122 +0100
> +++ gcc/c-family/c-common.h     2014-05-17 08:49:49.460516606 +0100
> @@ -297,8 +297,6 @@ enum c_tree_index
>      CTI_C99_FUNCTION_NAME_DECL,
>      CTI_SAVED_FUNCTION_NAME_DECLS,
>
> -    CTI_VOID_ZERO,
> -
>      CTI_NULL,
>
>      CTI_MAX
> @@ -430,9 +428,6 @@ #define pretty_function_name_decl_node      c
>  #define c99_function_name_decl_node            
> c_global_trees[CTI_C99_FUNCTION_NAME_DECL]
>  #define saved_function_name_decls      
> c_global_trees[CTI_SAVED_FUNCTION_NAME_DECLS]
>
> -/* A node for `((void) 0)'.  */
> -#define void_zero_node                  c_global_trees[CTI_VOID_ZERO]
> -
>  /* The node for C++ `__null'.  */
>  #define null_node                       c_global_trees[CTI_NULL]
>
> Index: gcc/c-family/c-common.c
> ===================================================================
> --- gcc/c-family/c-common.c     2014-05-11 21:21:30.400588654 +0100
> +++ gcc/c-family/c-common.c     2014-05-17 08:49:49.462516624 +0100
> @@ -5524,10 +5524,6 @@ c_common_nodes_and_builtins (void)
>      TYPE_NAME (void_type_node) = void_name;
>    }
>
> -  /* This node must not be shared.  */
> -  void_zero_node = make_int_cst (1, 1);
> -  TREE_TYPE (void_zero_node) = void_type_node;
> -
>    void_list_node = build_void_list_node ();
>
>    /* Make a type to be the domain of a few array types
> Index: gcc/c-family/c-pretty-print.c
> ===================================================================
> --- gcc/c-family/c-pretty-print.c       2014-05-06 18:38:50.985234029 +0100
> +++ gcc/c-family/c-pretty-print.c       2014-05-17 08:49:49.463516633 +0100
> @@ -906,6 +906,15 @@ pp_c_string_literal (c_pretty_printer *p
>    pp_doublequote (pp);
>  }
>
> +/* Pretty-print a VOID_CST (void_node).  */
> +
> +static void
> +pp_c_void_constant (c_pretty_printer *pp)
> +{
> +  pp_c_type_cast (pp, void_type_node);
> +  pp_string (pp, "0");
> +}
> +
>  /* Pretty-print an INTEGER literal.  */
>
>  static void
> @@ -1136,6 +1145,10 @@ c_pretty_printer::constant (tree e)
>
>    switch (code)
>      {
> +    case VOID_CST:
> +      pp_c_void_constant (this);
> +      break;
> +
>      case INTEGER_CST:
>        {
>         tree type = TREE_TYPE (e);
> @@ -1241,6 +1254,7 @@ c_pretty_printer::primary_expression (tr
>        translate_string ("<return-value>");
>        break;
>
> +    case VOID_CST:
>      case INTEGER_CST:
>      case REAL_CST:
>      case FIXED_CST:
> @@ -2131,6 +2145,10 @@ c_pretty_printer::expression (tree e)
>  {
>    switch (TREE_CODE (e))
>      {
> +    case VOID_CST:
> +      pp_c_void_constant (this);
> +      break;
> +
>      case INTEGER_CST:
>        pp_c_integer_constant (this, e);
>        break;
> Index: gcc/c-family/cilk.c
> ===================================================================
> --- gcc/c-family/cilk.c 2014-05-06 18:38:50.986234040 +0100
> +++ gcc/c-family/cilk.c 2014-05-17 08:49:49.463516633 +0100
> @@ -997,6 +997,7 @@ extract_free_variables (tree t, struct w
>      {
>      case ERROR_MARK:
>      case IDENTIFIER_NODE:
> +    case VOID_CST:
>      case INTEGER_CST:
>      case REAL_CST:
>      case FIXED_CST:
> Index: gcc/c-family/c-ubsan.c
> ===================================================================
> --- gcc/c-family/c-ubsan.c      2014-05-01 21:50:09.877008530 +0100
> +++ gcc/c-family/c-ubsan.c      2014-05-17 08:49:49.463516633 +0100
> @@ -95,7 +95,7 @@ ubsan_instrument_division (location_t lo
>        tt = build_call_expr_loc (loc, tt, 3, data, ubsan_encode_value (op0),
>                                 ubsan_encode_value (op1));
>      }
> -  t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_zero_node);
> +  t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_node);
>
>    return t;
>  }
> @@ -178,7 +178,7 @@ ubsan_instrument_shift (location_t loc,
>        tt = build_call_expr_loc (loc, tt, 3, data, ubsan_encode_value (op0),
>                                 ubsan_encode_value (op1));
>      }
> -  t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_zero_node);
> +  t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_node);
>
>    return t;
>  }
> @@ -207,7 +207,7 @@ ubsan_instrument_vla (location_t loc, tr
>        tt = builtin_decl_explicit (bcode);
>        tt = build_call_expr_loc (loc, tt, 2, data, ubsan_encode_value (size));
>      }
> -  t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_zero_node);
> +  t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_node);
>
>    return t;
>  }
> Index: gcc/c/c-array-notation.c
> ===================================================================
> --- gcc/c/c-array-notation.c    2014-04-22 09:05:21.366691542 +0100
> +++ gcc/c/c-array-notation.c    2014-05-17 08:49:49.460516606 +0100
> @@ -1279,7 +1279,7 @@ expand_array_notations (tree *tp, int *w
>          A[x:y:z];
>          A[x:y];
>          Replace those with just void zero node.  */
> -      *tp = void_zero_node;
> +      *tp = void_node;
>      default:
>        break;
>      }
> Index: gcc/cp/cvt.c
> ===================================================================
> --- gcc/cp/cvt.c        2014-05-13 07:54:45.420524702 +0100
> +++ gcc/cp/cvt.c        2014-05-17 08:49:49.464516642 +0100
> @@ -1285,7 +1285,7 @@ convert_to_void (tree expr, impl_conv_vo
>             }
>         else
>           return error_mark_node;
> -       expr = void_zero_node;
> +       expr = void_node;
>        }
>      else if (implicit != ICV_CAST && probe == expr && is_overloaded_fn 
> (probe))
>        {
> @@ -1415,7 +1415,7 @@ convert_to_void (tree expr, impl_conv_vo
>        expr = build1 (CONVERT_EXPR, void_type_node, expr);
>      }
>    if (! TREE_SIDE_EFFECTS (expr))
> -    expr = void_zero_node;
> +    expr = void_node;
>    return expr;
>  }
>
> Index: gcc/cp/cp-array-notation.c
> ===================================================================
> --- gcc/cp/cp-array-notation.c  2014-01-02 22:16:12.356353350 +0000
> +++ gcc/cp/cp-array-notation.c  2014-05-17 08:49:49.464516642 +0100
> @@ -181,7 +181,7 @@ replace_invariant_exprs (tree *node)
>           if (VOID_TYPE_P (TREE_TYPE (t)))
>             {
>               finish_expr_stmt (t);
> -             new_var = void_zero_node;
> +             new_var = void_node;
>             }
>           else
>             new_var = get_temp_regvar (TREE_TYPE (t), t);
> @@ -1126,6 +1126,7 @@ expand_array_notation_exprs (tree t)
>      {
>      case ERROR_MARK:
>      case IDENTIFIER_NODE:
> +    case VOID_CST:
>      case INTEGER_CST:
>      case REAL_CST:
>      case FIXED_CST:
> Index: gcc/cp/error.c
> ===================================================================
> --- gcc/cp/error.c      2014-04-11 09:33:54.568167858 +0100
> +++ gcc/cp/error.c      2014-05-17 08:49:49.465516651 +0100
> @@ -1913,6 +1913,7 @@ dump_expr (cxx_pretty_printer *pp, tree
>         pp_cxx_ws_string (pp, M_("<unknown>"));
>        break;
>
> +    case VOID_CST:
>      case INTEGER_CST:
>      case REAL_CST:
>      case STRING_CST:
> Index: gcc/cp/cxx-pretty-print.c
> ===================================================================
> --- gcc/cp/cxx-pretty-print.c   2014-01-02 22:16:12.811356978 +0000
> +++ gcc/cp/cxx-pretty-print.c   2014-05-17 08:49:49.465516651 +0100
> @@ -403,6 +403,7 @@ cxx_pretty_printer::primary_expression (
>  {
>    switch (TREE_CODE (t))
>      {
> +    case VOID_CST:
>      case INTEGER_CST:
>      case REAL_CST:
>      case COMPLEX_CST:
> @@ -690,7 +691,7 @@ pp_cxx_new_expression (cxx_pretty_printe
>           pp_left_paren (pp);
>           if (TREE_CODE (init) == TREE_LIST)
>             pp_c_expression_list (pp, init);
> -         else if (init == void_zero_node)
> +         else if (init == void_node)
>             ;                   /* OK, empty initializer list.  */
>           else
>             pp->expression (init);
> @@ -1028,6 +1029,7 @@ cxx_pretty_printer::expression (tree t)
>    switch (TREE_CODE (t))
>      {
>      case STRING_CST:
> +    case VOID_CST:
>      case INTEGER_CST:
>      case REAL_CST:
>      case COMPLEX_CST:
> Index: gcc/cp/decl.c
> ===================================================================
> --- gcc/cp/decl.c       2014-05-13 07:54:45.418524683 +0100
> +++ gcc/cp/decl.c       2014-05-17 08:49:49.467516669 +0100
> @@ -6830,7 +6830,7 @@ register_dtor_fn (tree decl)
>
>    type = TREE_TYPE (decl);
>    if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
> -    return void_zero_node;
> +    return void_node;
>
>    /* If we're using "__cxa_atexit" (or "__cxa_thread_atexit" or
>       "__aeabi_atexit"), and DECL is a class object, we can just pass the
> @@ -7077,7 +7077,7 @@ expand_static_init (tree decl, tree init
>
>           TARGET_EXPR_CLEANUP (begin)
>             = build3 (COND_EXPR, void_type_node, flag,
> -                     void_zero_node,
> +                     void_node,
>                       build_call_n (abort_fn, 1, guard_addr));
>           CLEANUP_EH_ONLY (begin) = 1;
>
> @@ -8425,7 +8425,7 @@ compute_array_index_type (tree name, tre
>               tree comp = build2 (LT_EXPR, boolean_type_node, itype,
>                                   ssize_int (-1));
>               comp = build3 (COND_EXPR, void_type_node, comp,
> -                            throw_bad_array_length (), void_zero_node);
> +                            throw_bad_array_length (), void_node);
>               finish_expr_stmt (comp);
>             }
>           else if (flag_sanitize & SANITIZE_VLA)
> Index: gcc/cp/init.c
> ===================================================================
> --- gcc/cp/init.c       2014-05-17 07:59:02.511986086 +0100
> +++ gcc/cp/init.c       2014-05-17 08:49:49.468516678 +0100
> @@ -2116,7 +2116,7 @@ build_raw_new_expr (vec<tree, va_gc> *pl
>    if (init == NULL)
>      init_list = NULL_TREE;
>    else if (init->is_empty ())
> -    init_list = void_zero_node;
> +    init_list = void_node;
>    else
>      init_list = build_tree_list_vec (init);
>
> @@ -2931,7 +2931,7 @@ build_new_1 (vec<tree, va_gc> **placemen
>
>               TARGET_EXPR_CLEANUP (begin)
>                 = build3 (COND_EXPR, void_type_node, sentry,
> -                         cleanup, void_zero_node);
> +                         cleanup, void_node);
>
>               end = build2 (MODIFY_EXPR, TREE_TYPE (sentry),
>                             sentry, boolean_false_node);
> @@ -3594,7 +3594,7 @@ build_vec_init (tree base, tree maxindex
>           else
>             throw_call = throw_bad_array_new_length ();
>           length_check = build3 (COND_EXPR, void_type_node, length_check,
> -                                throw_call, void_zero_node);
> +                                throw_call, void_node);
>           finish_expr_stmt (length_check);
>         }
>
> @@ -4016,7 +4016,7 @@ build_delete (tree otype, tree addr, spe
>         }
>
>        if (auto_delete != sfk_deleting_destructor)
> -       return void_zero_node;
> +       return void_node;
>
>        return build_op_delete_call (DELETE_EXPR, addr,
>                                    cxx_sizeof_nowarn (type),
> @@ -4104,8 +4104,7 @@ build_delete (tree otype, tree addr, spe
>         }
>
>        if (ifexp != integer_one_node)
> -       expr = build3 (COND_EXPR, void_type_node,
> -                      ifexp, expr, void_zero_node);
> +       expr = build3 (COND_EXPR, void_type_node, ifexp, expr, void_node);
>
>        return expr;
>      }
> @@ -4150,7 +4149,7 @@ push_base_cleanups (void)
>               if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo)))
>                 {
>                   expr = build3 (COND_EXPR, void_type_node, cond,
> -                                expr, void_zero_node);
> +                                expr, void_node);
>                   finish_decl_cleanup (NULL_TREE, expr);
>                 }
>             }
> Index: gcc/cp/mangle.c
> ===================================================================
> --- gcc/cp/mangle.c     2014-05-17 07:59:02.516986130 +0100
> +++ gcc/cp/mangle.c     2014-05-17 08:49:49.468516678 +0100
> @@ -2812,7 +2812,7 @@ write_expression (tree expr)
>         {
>           if (init)
>             write_string ("pi");
> -         if (init && init != void_zero_node)
> +         if (init && init != void_node)
>             for (t = init; t; t = TREE_CHAIN (t))
>               write_expression (TREE_VALUE (t));
>           write_char ('E');
> Index: gcc/cp/semantics.c
> ===================================================================
> --- gcc/cp/semantics.c  2014-05-14 16:41:49.734088647 +0100
> +++ gcc/cp/semantics.c  2014-05-17 08:49:49.470516696 +0100
> @@ -1083,7 +1083,7 @@ finish_break_stmt (void)
>       block_may_fallthru returns true when given something it does not
>       understand.  */
>    if (!block_may_fallthru (cur_stmt_list))
> -    return void_zero_node;
> +    return void_node;
>    return add_stmt (build_stmt (input_location, BREAK_STMT));
>  }
>
> @@ -2095,7 +2095,7 @@ empty_expr_stmt_p (tree expr_stmt)
>  {
>    tree body = NULL_TREE;
>
> -  if (expr_stmt == void_zero_node)
> +  if (expr_stmt == void_node)
>      return true;
>
>    if (expr_stmt)
> Index: gcc/cp/pt.c
> ===================================================================
> --- gcc/cp/pt.c 2014-05-11 21:21:39.253680836 +0100
> +++ gcc/cp/pt.c 2014-05-17 08:49:49.472516714 +0100
> @@ -10908,7 +10908,7 @@ #define RETURN(EXP) do { r = (EXP); goto
>                 /* Set up DECL_TEMPLATE_INFO so that we can get at the
>                    NSDMI in perform_member_init.  Still set DECL_INITIAL
>                    so that we know there is one.  */
> -               DECL_INITIAL (r) = void_zero_node;
> +               DECL_INITIAL (r) = void_node;
>                 gcc_assert (DECL_LANG_SPECIFIC (r) == NULL);
>                 retrofit_lang_decl (r);
>                 DECL_TEMPLATE_INFO (r) = build_template_info (t, args);
> @@ -12283,6 +12283,7 @@ tsubst (tree t, tree args, tsubst_flags_
>        }
>        break;
>
> +    case VOID_CST:
>      case INTEGER_CST:
>      case REAL_CST:
>      case STRING_CST:
> @@ -13042,6 +13043,10 @@ tsubst_copy (tree t, tree args, tsubst_f
>        error ("use %<...%> to expand argument pack");
>        return error_mark_node;
>
> +    case VOID_CST:
> +      gcc_checking_assert (t == void_node && VOID_TYPE_P (TREE_TYPE (t)));
> +      return t;
> +
>      case INTEGER_CST:
>      case REAL_CST:
>      case STRING_CST:
> @@ -14566,7 +14571,7 @@ #define RECUR(NODE)                                   
>           \
>         else
>           {
>             init_vec = make_tree_vector ();
> -           if (init == void_zero_node)
> +           if (init == void_node)
>               gcc_assert (init_vec != NULL);
>             else
>               {
> @@ -15222,9 +15227,9 @@ #define RECUR(NODE)                                   
>           \
>         cur_stmt_expr = old_stmt_expr;
>
>         /* If the resulting list of expression statement is empty,
> -          fold it further into void_zero_node.  */
> +          fold it further into void_node.  */
>         if (empty_expr_stmt_p (stmt_expr))
> -         stmt_expr = void_zero_node;
> +         stmt_expr = void_node;
>
>         RETURN (stmt_expr);
>        }
> @@ -21509,9 +21514,11 @@ build_non_dependent_expr (tree expr)
>       cannot be used to initialize a "char *".  */
>    if (TREE_CODE (expr) == STRING_CST)
>      return expr;
> -  /* Preserve arithmetic constants, as an optimization -- there is no
> +  /* Preserve void and arithmetic constants, as an optimization -- there is 
> no
>       reason to create a new node.  */
> -  if (TREE_CODE (expr) == INTEGER_CST || TREE_CODE (expr) == REAL_CST)
> +  if (TREE_CODE (expr) == VOID_CST
> +      || TREE_CODE (expr) == INTEGER_CST
> +      || TREE_CODE (expr) == REAL_CST)
>      return expr;
>    /* Preserve THROW_EXPRs -- all throw-expressions have type "void".
>       There is at least one place where we want to know that a
> Index: gcc/cp/tree.c
> ===================================================================
> --- gcc/cp/tree.c       2014-05-11 21:21:39.251680821 +0100
> +++ gcc/cp/tree.c       2014-05-17 08:49:49.473516723 +0100
> @@ -2620,6 +2620,11 @@ cp_tree_equal (tree t1, tree t2)
>
>    switch (code1)
>      {
> +    case VOID_CST:
> +      /* There's only a single VOID_CST node, so we should never reach
> +        here.  */
> +      gcc_unreachable ();
> +
>      case INTEGER_CST:
>        return tree_int_cst_equal (t1, t2);
>
> @@ -2947,7 +2952,7 @@ member_p (const_tree decl)
>  tree
>  build_dummy_object (tree type)
>  {
> -  tree decl = build1 (NOP_EXPR, build_pointer_type (type), void_zero_node);
> +  tree decl = build1 (NOP_EXPR, build_pointer_type (type), void_node);
>    return cp_build_indirect_ref (decl, RO_NULL, tf_warning_or_error);
>  }
>
> @@ -2997,7 +3002,7 @@ is_dummy_object (const_tree ob)
>    if (INDIRECT_REF_P (ob))
>      ob = TREE_OPERAND (ob, 0);
>    return (TREE_CODE (ob) == NOP_EXPR
> -         && TREE_OPERAND (ob, 0) == void_zero_node);
> +         && TREE_OPERAND (ob, 0) == void_node);
>  }
>
>  /* Returns 1 iff type T is something we want to treat as a scalar type for
> @@ -3775,7 +3780,7 @@ stabilize_expr (tree exp, tree* initp)
>    else if (VOID_TYPE_P (TREE_TYPE (exp)))
>      {
>        init_expr = exp;
> -      exp = void_zero_node;
> +      exp = void_node;
>      }
>    /* There are no expressions with REFERENCE_TYPE, but there can be call
>       arguments with such a type; just treat it as a pointer.  */
> Index: gcc/cp/typeck.c
> ===================================================================
> --- gcc/cp/typeck.c     2014-05-17 07:59:02.511986086 +0100
> +++ gcc/cp/typeck.c     2014-05-17 08:49:49.474516732 +0100
> @@ -8418,7 +8418,7 @@ check_return_expr (tree retval, bool *no
>        else
>         {
>           if (!retval)
> -           retval = void_zero_node;
> +           retval = void_node;
>           auto_node = type_uses_auto (current_function_auto_return_pattern);
>           type = do_auto_deduction (current_function_auto_return_pattern,
>                                     retval, auto_node);
> Index: gcc/cp/typeck2.c
> ===================================================================
> --- gcc/cp/typeck2.c    2014-05-06 18:38:58.635319329 +0100
> +++ gcc/cp/typeck2.c    2014-05-17 08:49:49.474516732 +0100
> @@ -1856,7 +1856,7 @@ build_functional_cast (tree exp, tree pa
>        if (parms == NULL_TREE)
>         {
>           if (VOID_TYPE_P (type))
> -           return void_zero_node;
> +           return void_node;
>           return build_value_init (cv_unqualified (type), complain);
>         }
>

Reply via email to