summaryrefslogtreecommitdiff
path: root/gcc/cp/semantics.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/semantics.cc')
-rw-r--r--gcc/cp/semantics.cc23
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