aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/semantics.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/semantics.c')
-rw-r--r--gcc/cp/semantics.c68
1 files changed, 46 insertions, 22 deletions
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index cc1e2ea..db9e4d2 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -1449,8 +1449,12 @@ finish_stmt_expr (tree rtl_expr)
tree result;
/* If the last thing in the statement-expression was not an
- expression-statement, then it has type `void'. */
- if (!last_expr_type)
+ expression-statement, then it has type `void'. In a template, we
+ cannot distinguish the case where the last expression-statement
+ had a dependent type from the case where the last statement was
+ not an expression-statement. Therefore, we (incorrectly) treat
+ the STMT_EXPR as dependent in that case. */
+ if (!last_expr_type && !processing_template_decl)
last_expr_type = void_type_node;
result = build_min (STMT_EXPR, last_expr_type, last_tree);
TREE_SIDE_EFFECTS (result) = 1;
@@ -1482,16 +1486,32 @@ finish_stmt_expr (tree rtl_expr)
tree
finish_call_expr (tree fn, tree args, bool disallow_virtual)
{
+ tree result;
+ tree orig_fn;
+ tree orig_args;
+
if (fn == error_mark_node || args == error_mark_node)
return error_mark_node;
- if (processing_template_decl)
- return build_nt (CALL_EXPR, fn, args, NULL_TREE);
-
/* ARGS should be a list of arguments. */
my_friendly_assert (!args || TREE_CODE (args) == TREE_LIST,
20020712);
+ orig_fn = fn;
+ orig_args = args;
+
+ if (processing_template_decl)
+ {
+ if (type_dependent_expression_p (fn)
+ || any_type_dependent_arguments_p (args))
+ return build_nt (CALL_EXPR, fn, args);
+ if (!BASELINK_P (fn)
+ && TREE_CODE (fn) != PSEUDO_DTOR_EXPR
+ && TREE_TYPE (fn) != unknown_type_node)
+ fn = build_non_dependent_expr (fn);
+ args = build_non_dependent_args (orig_args);
+ }
+
/* A reference to a member function will appear as an overloaded
function (rather than a BASELINK) if an unqualified name was used
to refer to it. */
@@ -1512,6 +1532,7 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual)
}
}
+ result = NULL_TREE;
if (BASELINK_P (fn))
{
tree object;
@@ -1551,17 +1572,22 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual)
object = build_dummy_object (DECL_CONTEXT (representative_fn));
}
- return build_new_method_call (object, fn, args, NULL_TREE,
- (disallow_virtual
- ? LOOKUP_NONVIRTUAL : 0));
+ if (processing_template_decl)
+ {
+ if (type_dependent_expression_p (object))
+ return build_nt (CALL_EXPR, orig_fn, orig_args);
+ object = build_non_dependent_expr (object);
+ }
+
+ result = build_new_method_call (object, fn, args, NULL_TREE,
+ (disallow_virtual
+ ? LOOKUP_NONVIRTUAL : 0));
}
else if (is_overloaded_fn (fn))
/* A call to a namespace-scope function. */
- return build_new_function_call (fn, args);
+ result = build_new_function_call (fn, args);
else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR)
{
- tree result;
-
if (args)
error ("arguments to destructor are not allowed");
/* Mark the pseudo-destructor call as having side-effects so
@@ -1570,20 +1596,18 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual)
void_type_node,
TREE_OPERAND (fn, 0));
TREE_SIDE_EFFECTS (result) = 1;
- return result;
}
else if (CLASS_TYPE_P (TREE_TYPE (fn)))
- {
- /* If the "function" is really an object of class type, it might
- have an overloaded `operator ()'. */
- tree result;
- result = build_new_op (CALL_EXPR, LOOKUP_NORMAL, fn, args, NULL_TREE);
- if (result)
- return result;
- }
+ /* If the "function" is really an object of class type, it might
+ have an overloaded `operator ()'. */
+ result = build_new_op (CALL_EXPR, LOOKUP_NORMAL, fn, args, NULL_TREE);
+ if (!result)
+ /* A call where the function is unknown. */
+ result = build_function_call (fn, args);
- /* A call where the function is unknown. */
- return build_function_call (fn, args);
+ if (processing_template_decl)
+ return build (CALL_EXPR, TREE_TYPE (result), orig_fn, orig_args);
+ return result;
}
/* Finish a call to a postfix increment or decrement or EXPR. (Which