diff options
Diffstat (limited to 'gcc/cp/semantics.cc')
-rw-r--r-- | gcc/cp/semantics.cc | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index a7f6449dafd..ab48f11c9be 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -609,7 +609,17 @@ set_cleanup_locs (tree stmts, location_t loc) { if (TREE_CODE (stmts) == CLEANUP_STMT) { - protected_set_expr_location (CLEANUP_EXPR (stmts), loc); + tree t = CLEANUP_EXPR (stmts); + protected_set_expr_location (t, loc); + /* Avoid locus differences for C++ cdtor calls depending on whether + cdtor_returns_this: a conversion to void is added to discard the return + value, and this conversion ends up carrying the location, and when it + gets discarded, the location is lost. So hold it in the call as + well. */ + if (TREE_CODE (t) == NOP_EXPR + && TREE_TYPE (t) == void_type_node + && TREE_CODE (TREE_OPERAND (t, 0)) == CALL_EXPR) + protected_set_expr_location (TREE_OPERAND (t, 0), loc); set_cleanup_locs (CLEANUP_BODY (stmts), loc); } else if (TREE_CODE (stmts) == STATEMENT_LIST) @@ -656,7 +666,8 @@ do_pushlevel (scope_kind sk) /* Queue a cleanup. CLEANUP is an expression/statement to be executed when the current scope is exited. EH_ONLY is true when this is not - meant to apply to normal control flow transfer. */ + meant to apply to normal control flow transfer. DECL is the VAR_DECL + being cleaned up, if any, or null for temporaries or subobjects. */ void push_cleanup (tree decl, tree cleanup, bool eh_only) @@ -2679,13 +2690,13 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual, if (processing_template_decl) { - /* If FN is a local extern declaration or set thereof, look them up - again at instantiation time. */ + /* If FN is a local extern declaration (or set thereof) in a template, + look it up again at instantiation time. */ if (is_overloaded_fn (fn)) { tree ifn = get_first_fn (fn); if (TREE_CODE (ifn) == FUNCTION_DECL - && DECL_LOCAL_DECL_P (ifn)) + && dependent_local_decl_p (ifn)) orig_fn = DECL_NAME (ifn); } @@ -11241,7 +11252,7 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p, } else if (processing_template_decl) { - expr = instantiate_non_dependent_expr_sfinae (expr, complain); + expr = instantiate_non_dependent_expr_sfinae (expr, complain|tf_decltype); if (expr == error_mark_node) return error_mark_node; /* Keep processing_template_decl cleared for the rest of the function |