diff options
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 3 | ||||
-rw-r--r-- | gcc/cp/parser.c | 10 | ||||
-rw-r--r-- | gcc/cp/pt.c | 24 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 14 |
5 files changed, 42 insertions, 20 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5401141..66ac60e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,14 @@ +2009-03-30 Jason Merrill <jason@redhat.com> + + PR c++/38030, 38850, 39070 + * pt.c (type_dependent_expression_p_push): New fn. + (tsubst_copy_and_build) [CALL_EXPR]: Only do arg-dep lookup when the + substitution makes the call non-dependent. Preserve koenig_p. + * parser.c (cp_parser_postfix_expression): Only do arg-dep lookup + for non-dependent calls. + * semantics.c (finish_call_expr): Revert earlier changes. + * cp-tree.h: Revert change to finish_call_expr prototype. + 2009-03-29 Joseph Myers <joseph@codesourcery.com> PR preprocessor/34695 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ca19856..4fc86c3 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4602,6 +4602,7 @@ extern bool dependent_template_p (tree); extern bool dependent_template_id_p (tree, tree); extern bool type_dependent_expression_p (tree); extern bool any_type_dependent_arguments_p (const_tree); +extern bool type_dependent_expression_p_push (tree); extern bool value_dependent_expression_p (tree); extern bool any_value_dependent_elements_p (const_tree); extern bool dependent_omp_for_p (tree, tree, tree, tree); @@ -4761,7 +4762,7 @@ extern tree finish_stmt_expr_expr (tree, tree); extern tree finish_stmt_expr (tree, bool); extern tree stmt_expr_value_expr (tree); extern tree perform_koenig_lookup (tree, tree); -extern tree finish_call_expr (tree, tree, bool, int, +extern tree finish_call_expr (tree, tree, bool, bool, tsubst_flags_t); extern tree finish_increment_expr (tree, enum tree_code); extern tree finish_this_expr (void); diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 09e19a2..eacf5e9 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -4738,8 +4738,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, if (args) { koenig_p = true; - postfix_expression - = perform_koenig_lookup (postfix_expression, args); + if (!any_type_dependent_arguments_p (args)) + postfix_expression + = perform_koenig_lookup (postfix_expression, args); } else postfix_expression @@ -4761,8 +4762,9 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p, if (!DECL_FUNCTION_MEMBER_P (fn)) { koenig_p = true; - postfix_expression - = perform_koenig_lookup (postfix_expression, args); + if (!any_type_dependent_arguments_p (args)) + postfix_expression + = perform_koenig_lookup (postfix_expression, args); } } } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 5092c72..c3873cd 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -11450,7 +11450,11 @@ tsubst_copy_and_build (tree t, not appropriate, even if an unqualified-name was used to denote the function. */ && !DECL_FUNCTION_MEMBER_P (get_first_fn (function))) - || TREE_CODE (function) == IDENTIFIER_NODE)) + || TREE_CODE (function) == IDENTIFIER_NODE) + /* Only do this when substitution turns a dependent call + into a non-dependent call. */ + && type_dependent_expression_p_push (t) + && !any_type_dependent_arguments_p (call_args)) function = perform_koenig_lookup (function, call_args); if (TREE_CODE (function) == IDENTIFIER_NODE) @@ -11481,12 +11485,9 @@ tsubst_copy_and_build (tree t, /*fn_p=*/NULL, complain)); } - /* Pass -1 for koenig_p so that build_new_function_call will - allow hidden friends found by arg-dependent lookup at template - parsing time. */ return finish_call_expr (function, call_args, /*disallow_virtual=*/qualified_p, - /*koenig_p*/-1, + koenig_p, complain); } @@ -16454,6 +16455,19 @@ type_dependent_expression_p (tree expression) return (dependent_type_p (TREE_TYPE (expression))); } +/* Like type_dependent_expression_p, but it also works while not processing + a template definition, i.e. during substitution or mangling. */ + +bool +type_dependent_expression_p_push (tree expr) +{ + bool b; + ++processing_template_decl; + b = type_dependent_expression_p (expr); + --processing_template_decl; + return b; +} + /* Returns TRUE if ARGS (a TREE_LIST of arguments to a function call) contains a type-dependent expression. */ diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 71fc43e..5357077 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -1836,14 +1836,10 @@ perform_koenig_lookup (tree fn, tree args) qualified. For example a call to `X::f' never generates a virtual call.) - KOENIG_P is 1 if we want to perform argument-dependent lookup, - -1 if we don't, but we want to accept functions found by previous - argument-dependent lookup, and 0 if we want nothing to do with it. - Returns code for the call. */ tree -finish_call_expr (tree fn, tree args, bool disallow_virtual, int koenig_p, +finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p, tsubst_flags_t complain) { tree result; @@ -1866,7 +1862,7 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, int koenig_p, || any_type_dependent_arguments_p (args)) { result = build_nt_call_list (fn, args); - KOENIG_LOOKUP_P (result) = koenig_p > 0; + KOENIG_LOOKUP_P (result) = koenig_p; if (cfun) { do @@ -1956,7 +1952,7 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, int koenig_p, if (!result) /* A call to a namespace-scope function. */ - result = build_new_function_call (fn, args, koenig_p != 0, complain); + result = build_new_function_call (fn, args, koenig_p, complain); } else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR) { @@ -1982,9 +1978,7 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, int koenig_p, if (processing_template_decl) { result = build_call_list (TREE_TYPE (result), orig_fn, orig_args); - /* Don't repeat arg-dependent lookup at instantiation time if this call - is not type-dependent. */ - KOENIG_LOOKUP_P (result) = 0; + KOENIG_LOOKUP_P (result) = koenig_p; } return result; } |