diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-01-03 20:04:38 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-01-03 20:04:38 +0000 |
commit | bdb2219e7e699db95907d0558c04676024db9560 (patch) | |
tree | 3080ff7fbc3a73e39df1773fb9eda1ec24ad5334 /gcc | |
parent | 9bacae7e81f3a57b192176f2fccfd6eff61c95fa (diff) | |
download | gcc-bdb2219e7e699db95907d0558c04676024db9560.tar.gz |
* fold-const.c (fold) [COND_EXPR]: Avoid NOP_EXPRs better.
* integrate.c (copy_decl_for_inlining): Don't clear the rtl for
static/external decls.
cp/
* call.c (build_conditional_expr): Stabilize lvalues properly.
* cvt.c (ocp_convert): Don't build NOP_EXPRs of class type.
* tree.c (lvalue_p_1): Don't allow sloppy NOP_EXPRs as lvalues.
Don't allow CALL_EXPR or VA_ARG_EXPR, either.
* call.c (convert_like_real): Call decl_constant_value for an
IDENTITY_CONV even if there are no more conversions.
* cvt.c (build_up_reference): Don't push unnamed temps.
* decl2.c (do_namespace_alias): Namespace aliases are DECL_EXTERNAL.
* dump.c (cp_dump_tree): Don't try to dump class-specific fields
for a backend struct.
* except.c (wrap_cleanups_r, build_throw): Make
MUST_NOT_THROW_EXPRs void.
* init.c (expand_default_init): Update to handle MUST_NOT_THROW_EXPR.
* init.c (build_vec_delete_1): Pre-evaluate the base address.
* init.c (get_temp_regvar): Simplify logic.
* tree.c (cp_copy_res_decl_for_inlining): Only do debug tweaks if
our replacement is a decl.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@60851 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 26 | ||||
-rw-r--r-- | gcc/cp/call.c | 20 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 16 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 1 | ||||
-rw-r--r-- | gcc/cp/dump.c | 3 | ||||
-rw-r--r-- | gcc/cp/except.c | 4 | ||||
-rw-r--r-- | gcc/cp/init.c | 27 | ||||
-rw-r--r-- | gcc/cp/tree.c | 30 | ||||
-rw-r--r-- | gcc/fold-const.c | 6 | ||||
-rw-r--r-- | gcc/integrate.c | 7 |
11 files changed, 103 insertions, 42 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 37c1db7e3fc..b3fbf3b37b1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2003-01-02 Jason Merrill <jason@redhat.com> + * fold-const.c (fold) [COND_EXPR]: Avoid NOP_EXPRs better. + + * integrate.c (copy_decl_for_inlining): Don't clear the rtl for + static/external decls. + * c-common.c (finish_fname_decls): Put the DECL_STMTs inside the outermost scope. * c-decl.c (c_make_fname_decl): Push the decls there, too. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 344630d722d..cdc4127ccf0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -16,6 +16,32 @@ 2003-01-02 Jason Merrill <jason@redhat.com> + * call.c (build_conditional_expr): Stabilize lvalues properly. + * cvt.c (ocp_convert): Don't build NOP_EXPRs of class type. + * tree.c (lvalue_p_1): Don't allow sloppy NOP_EXPRs as lvalues. + Don't allow CALL_EXPR or VA_ARG_EXPR, either. + + * call.c (convert_like_real): Call decl_constant_value for an + IDENTITY_CONV even if there are no more conversions. + + * cvt.c (build_up_reference): Don't push unnamed temps. + + * decl2.c (do_namespace_alias): Namespace aliases are DECL_EXTERNAL. + + * dump.c (cp_dump_tree): Don't try to dump class-specific fields + for a backend struct. + + * except.c (wrap_cleanups_r, build_throw): Make + MUST_NOT_THROW_EXPRs void. + * init.c (expand_default_init): Update to handle MUST_NOT_THROW_EXPR. + + * init.c (build_vec_delete_1): Pre-evaluate the base address. + + * init.c (get_temp_regvar): Simplify logic. + + * tree.c (cp_copy_res_decl_for_inlining): Only do debug tweaks if + our replacement is a decl. + * decl.c (cp_make_fname_decl): Push the decls inside the outermost scope. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index bd4fb064cfd..00458c06248 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -2977,7 +2977,12 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3) { if (pedantic) pedwarn ("ISO C++ forbids omitting the middle term of a ?: expression"); - arg1 = arg2 = save_expr (arg1); + + /* Make sure that lvalues remain lvalues. See g++.oliva/ext1.C. */ + if (real_lvalue_p (arg1)) + arg2 = arg1 = stabilize_reference (arg1); + else + arg2 = arg1 = save_expr (arg1); } /* [expr.cond] @@ -3964,6 +3969,12 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner) case IDENTITY_CONV: if (type_unknown_p (expr)) expr = instantiate_type (totype, expr, tf_error | tf_warning); + /* Convert a non-array constant variable to its underlying value, unless we + are about to bind it to a reference, in which case we need to + leave it as an lvalue. */ + if (inner >= 0 + && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE) + expr = decl_constant_value (expr); return expr; case AMBIG_CONV: /* Call build_user_type_conversion again for the error. */ @@ -3979,13 +3990,6 @@ convert_like_real (tree convs, tree expr, tree fn, int argnum, int inner) if (expr == error_mark_node) return error_mark_node; - /* Convert a non-array constant variable to its underlying value, unless we - are about to bind it to a reference, in which case we need to - leave it as an lvalue. */ - if (TREE_CODE (convs) != REF_BIND - && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE) - expr = decl_constant_value (expr); - switch (TREE_CODE (convs)) { case RVALUE_CONV: diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index d6b50bbc4d3..48477735ac1 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -381,7 +381,8 @@ build_up_reference (tree type, tree arg, int flags, tree decl) { /* Automatic; make sure we handle the cleanup properly. */ maybe_push_cleanup_level (argtype); - arg = pushdecl (arg); + /* Don't push unnamed temps. Do set DECL_CONTEXT, though. */ + DECL_CONTEXT (arg) = current_function_decl; } /* Process the initializer for the declaration. */ @@ -654,6 +655,19 @@ ocp_convert (tree type, tree expr, int convtype, int flags) conversion. */ else if (TREE_CODE (type) == COMPLEX_TYPE) return fold (convert_to_complex (type, e)); + else if (TREE_CODE (e) == TARGET_EXPR) + { + /* Don't build a NOP_EXPR of class type. Instead, change the + type of the temporary. Only allow this for cv-qual changes, + though. */ + if (!same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (e)), + TYPE_MAIN_VARIANT (type))) + abort (); + TREE_TYPE (e) = TREE_TYPE (TARGET_EXPR_SLOT (e)) = type; + return e; + } + else if (CLASS_TYPE_P (type)) + abort (); else return fold (build1 (NOP_EXPR, type, e)); } diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 73e37ad5f1b..4e0b7fed1b7 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -4258,6 +4258,7 @@ do_namespace_alias (tree alias, tree namespace) /* Build the alias. */ alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node); DECL_NAMESPACE_ALIAS (alias) = namespace; + DECL_EXTERNAL (alias) = 1; pushdecl (alias); } diff --git a/gcc/cp/dump.c b/gcc/cp/dump.c index 9a0e76df025..b03dc82f134 100644 --- a/gcc/cp/dump.c +++ b/gcc/cp/dump.c @@ -273,6 +273,9 @@ cp_dump_tree (dump_info, t) return 1; } + if (! IS_AGGR_TYPE (t)) + break; + dump_child ("vfld", TYPE_VFIELD (t)); if (CLASSTYPE_TEMPLATE_SPECIALIZATION(t)) dump_string(di, "spec"); diff --git a/gcc/cp/except.c b/gcc/cp/except.c index 001d7f1bd12..44309e3ddfb 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -561,7 +561,7 @@ wrap_cleanups_r (tp, walk_subtrees, data) cleanup = TARGET_EXPR_CLEANUP (exp); if (cleanup) { - cleanup = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (cleanup), cleanup); + cleanup = build1 (MUST_NOT_THROW_EXPR, void_type_node, cleanup); TARGET_EXPR_CLEANUP (exp) = cleanup; } @@ -733,7 +733,7 @@ build_throw (exp) return error_mark_node; } - exp = build1 (MUST_NOT_THROW_EXPR, TREE_TYPE (exp), exp); + exp = build1 (MUST_NOT_THROW_EXPR, void_type_node, exp); /* Prepend the allocation. */ exp = build (COMPOUND_EXPR, TREE_TYPE (exp), allocate_expr, exp); if (temp_expr != void_zero_node) diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 36e4276e2e6..2fd0c50779b 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1206,13 +1206,16 @@ expand_default_init (binfo, true_exp, exp, init, flags) else init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags); - if (TREE_CODE (init) == TRY_CATCH_EXPR) - /* We need to protect the initialization of a catch parm - with a call to terminate(), which shows up as a TRY_CATCH_EXPR + if (TREE_CODE (init) == MUST_NOT_THROW_EXPR) + /* We need to protect the initialization of a catch parm with a + call to terminate(), which shows up as a MUST_NOT_THROW_EXPR around the TARGET_EXPR for the copy constructor. See - expand_start_catch_block. */ - TREE_OPERAND (init, 0) = build (INIT_EXPR, TREE_TYPE (exp), exp, - TREE_OPERAND (init, 0)); + initialize_handler_parm. */ + { + TREE_OPERAND (init, 0) = build (INIT_EXPR, TREE_TYPE (exp), exp, + TREE_OPERAND (init, 0)); + TREE_TYPE (init) = void_type_node; + } else init = build (INIT_EXPR, TREE_TYPE (exp), exp, init); TREE_SIDE_EFFECTS (init) = 1; @@ -2652,10 +2655,14 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, use_global_delete) if (controller) { TREE_OPERAND (controller, 1) = body; - return controller; + body = controller; } - else - return cp_convert (void_type_node, body); + + if (TREE_CODE (base) == SAVE_EXPR) + /* Pre-evaluate the SAVE_EXPR outside of the BIND_EXPR. */ + body = build (COMPOUND_EXPR, void_type_node, base, body); + + return cp_convert (void_type_node, body); } /* Create an unnamed variable of the indicated TYPE. */ @@ -2693,7 +2700,7 @@ get_temp_regvar (type, init) decl = create_temporary_var (type); if (building_stmt_tree ()) add_decl_stmt (decl); - if (!building_stmt_tree ()) + else SET_DECL_RTL (decl, assign_temp (type, 2, 0, 1)); finish_expr_stmt (build_modify_expr (decl, INIT_EXPR, init)); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 20d51d4ac18..ad062b7202a 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -93,13 +93,7 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues, allow_cast_as_lvalue) allow_cast_as_lvalue); case NOP_EXPR: - /* If expression doesn't change the type, we consider it as an - lvalue even when cast_as_lvalue extension isn't selected. - That's because parts of the compiler are alleged to be sloppy - about sticking in NOP_EXPR node for no good reason. */ - if (allow_cast_as_lvalue || - same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (ref)), - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (ref, 0))))) + if (allow_cast_as_lvalue) return lvalue_p_1 (TREE_OPERAND (ref, 0), treat_class_rvalues_as_lvalues, allow_cast_as_lvalue); @@ -179,9 +173,8 @@ lvalue_p_1 (ref, treat_class_rvalues_as_lvalues, allow_cast_as_lvalue) case CALL_EXPR: case VA_ARG_EXPR: - return ((treat_class_rvalues_as_lvalues - && IS_AGGR_TYPE (TREE_TYPE (ref))) - ? clk_class : clk_none); + /* Any class-valued call would be wrapped in a TARGET_EXPR. */ + return clk_none; case FUNCTION_DECL: /* All functions (except non-static-member functions) are @@ -2353,13 +2346,16 @@ cp_copy_res_decl_for_inlining (result, fn, caller, decl_map_, /* We have a named return value; copy the name and source position so we can get reasonable debugging information, and register the return variable as its equivalent. */ - DECL_NAME (var) = DECL_NAME (nrv); - DECL_SOURCE_LOCATION (var) = DECL_SOURCE_LOCATION (nrv); - DECL_ABSTRACT_ORIGIN (var) = DECL_ORIGIN (nrv); - /* Don't lose initialization info. */ - DECL_INITIAL (var) = DECL_INITIAL (nrv); - /* Don't forget that it needs to go in the stack. */ - TREE_ADDRESSABLE (var) = TREE_ADDRESSABLE (nrv); + if (TREE_CODE (var) == VAR_DECL) + { + DECL_NAME (var) = DECL_NAME (nrv); + DECL_SOURCE_LOCATION (var) = DECL_SOURCE_LOCATION (nrv); + DECL_ABSTRACT_ORIGIN (var) = DECL_ORIGIN (nrv); + /* Don't lose initialization info. */ + DECL_INITIAL (var) = DECL_INITIAL (nrv); + /* Don't forget that it needs to go in the stack. */ + TREE_ADDRESSABLE (var) = TREE_ADDRESSABLE (nrv); + } splay_tree_insert (decl_map, (splay_tree_key) nrv, diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 1454d414f09..0c53604e7d5 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -7002,7 +7002,11 @@ fold (expr) /* Avoid adding NOP_EXPRs in case this is an lvalue. */ if (TYPE_MAIN_VARIANT (comp_type) == TYPE_MAIN_VARIANT (type)) - comp_type = type; + { + comp_type = type; + comp_op0 = arg1; + comp_op1 = arg2; + } switch (comp_code) { diff --git a/gcc/integrate.c b/gcc/integrate.c index 7e1f29f5bb0..8feb845b9e4 100644 --- a/gcc/integrate.c +++ b/gcc/integrate.c @@ -394,7 +394,8 @@ copy_decl_for_inlining (decl, from_fn, to_fn) DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (decl); /* The new variable/label has no RTL, yet. */ - SET_DECL_RTL (copy, NULL_RTX); + if (!TREE_STATIC (copy) && !DECL_EXTERNAL (copy)) + SET_DECL_RTL (copy, NULL_RTX); /* These args would always appear unused, if not for this. */ TREE_USED (copy) = 1; @@ -405,10 +406,10 @@ copy_decl_for_inlining (decl, from_fn, to_fn) ; else if (DECL_CONTEXT (decl) != from_fn) /* Things that weren't in the scope of the function we're inlining - from aren't in the scope we're inlining too, either. */ + from aren't in the scope we're inlining to, either. */ ; else if (TREE_STATIC (decl)) - /* Function-scoped static variables should say in the original + /* Function-scoped static variables should stay in the original function. */ ; else |