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); > } >