aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/decl2.c
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2003-07-09 08:48:08 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2003-07-09 08:48:08 +0000
commitd17811fd1aad24d0f47d0b20679753b23803848b (patch)
tree1246373b84fbf4bb96eed29b458823d826bd18da /gcc/cp/decl2.c
parent844c00ed1626fba3304289f5f8c3531620b24d5f (diff)
downloadgcc-d17811fd1aad24d0f47d0b20679753b23803848b.zip
gcc-d17811fd1aad24d0f47d0b20679753b23803848b.tar.gz
gcc-d17811fd1aad24d0f47d0b20679753b23803848b.tar.bz2
fold-const.c (make_range): Do not access operand 1 for a zero-operand operator.
* fold-const.c (make_range): Do not access operand 1 for a zero-operand operator. 2003-07-08 Mark Mitchell <mark@codesourcery.com> * cp-tree.def (NON_DEPENDENT_EXPR): New node. * cp-tree.h (build_call_from_tree): Remove. (build_member_call): Likewise. (dependent_template_arg_p): Remove. (any_dependent_template_arguments_p): New function. (dependent_template_id_p): Likewise. (any_type_dependent_arguments_p): Likewise. (build_non_dependent_expr): Likewise. (build_non_dependent_args): Likewise. (build_x_compound_expr): Adjust prototype. * call.c (build_new_method_call): Handle non-dependent expressions correctly. * decl2.c (grok_array_decl): Likewise. (build_offset_ref_call_from_tree): Likewise. (build_call_from_tree): Remove. * error.c (dump_decl): Handle NON_DEPENDENT_EXPR. (dump_expr): Likewise. * init.c (build_member_call): Remove. * mangle.c (write_expression): Update handling for template-ids. * parser.c (cp_parser_primary_expression): Use any_dependent_template_arguments_p. Update constant-expression handling. (cp_parser_postfix_expression): Use any_type_dependent_arguments_p. Simplify call processing. (cp_parser_unary_expression): Simplify. (cp_parser_expression): Adjust for changes to build_x_compound_expr. (cp_parser_template_argument): Implement standard-conforming parsing of non-type template arguments. (cp_parser_direct_declarator): Use cp_parser_fold_non_dependent_expr. (cp_parser_fold_non_dependent_expr): New function. (cp_parser_next_token_ends_template_argument_p): Likewise. * pt.c (convert_template_argument): Do not call maybe_fold_nontype_arg. (tsubst_baselink): Likewise. (tsubst_copy_and_build): Share common code. Make sizeof/alignof processing work correctly for non-dependent expressions. Adjust handling of COMPOUND_EXPR. Simplify call processing. (value_dependent_expression_p): Deal with functional casts and sizeof/alignof correctly. (type_dependent_expression_p): Handle overloaded functions. (any_type_dependent_arguments_p): New function. (any_dependent_template_arguments_p): Likewise. (dependent_template_p): Treat SCOPE_REFs as dependent. (dependent_template_id_p): Simplify. (build_non_dependent_expr): New function. (build_non_dependent_args): Likewise. * semantics.c (finish_stmt_expr): Don't make dependent statement-expresions have void type. (finish_call_expr): Handle non-dependent expressions correctly. * tree.c (lvalue_p_1): Treat NON_DEPENDENT_EXPRs as lvalues. * typeck.c (cxx_sizeof_or_alignof_type): Give the expression type size_t, even in templates. (expr_sizeof): Likewise. (finish_class_member_access_expr): Handle non-dependent expressions correctly. (build_x_indirect_ref): Likewise. (build_x_binary_op): Likewise. (build_x_unary_op): Likewise. (build_x_conditional_expr): Likewise. (build_x_compound_expr): Likewise. * typeck2.c (build_x_arrow): Likewise. 2003-07-08 Mark Mitchell <mark@codesourcery.com> * g++.dg/abi/mangle17.C: Make sure template expressions are dependent. * g++.dg/abi/mangle4.C: Mark erroneous casts. * g++.dg/debug/debug7.C: Mark erronous new-declarator. * g++.dg/opt/stack1.C: Remove erroneous code. * g++.dg/parse/template7.C: New test. * g++.dg/template/dependent-expr1.C: Mark erroneous code. * g++.old-deja/g++.pt/crash4.C: Likewise. 2003-07-09 Mark Mitchell <mark@codesourcery.com> * gcj/array.h (JvPrimClass): Don't parenthesize the output. From-SVN: r69130
Diffstat (limited to 'gcc/cp/decl2.c')
-rw-r--r--gcc/cp/decl2.c192
1 files changed, 89 insertions, 103 deletions
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 7a2399a..c77e503 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -398,59 +398,77 @@ grokclassfn (tree ctype, tree function, enum overload_flags flags, tree quals)
tree
grok_array_decl (tree array_expr, tree index_exp)
{
- tree type = TREE_TYPE (array_expr);
- tree p1, p2, i1, i2;
+ tree type;
+ tree expr;
+ tree orig_array_expr = array_expr;
+ tree orig_index_exp = index_exp;
- if (type == error_mark_node || index_exp == error_mark_node)
+ if (error_operand_p (array_expr) || error_operand_p (index_exp))
return error_mark_node;
+
if (processing_template_decl)
- return build_min (ARRAY_REF, type ? TREE_TYPE (type) : NULL_TREE,
- array_expr, index_exp);
+ {
+ if (type_dependent_expression_p (array_expr)
+ || type_dependent_expression_p (index_exp))
+ return build_min_nt (ARRAY_REF, array_expr, index_exp);
+ array_expr = build_non_dependent_expr (array_expr);
+ index_exp = build_non_dependent_expr (index_exp);
+ }
+ type = TREE_TYPE (array_expr);
my_friendly_assert (type, 20030626);
-
type = non_reference (type);
/* If they have an `operator[]', use that. */
if (IS_AGGR_TYPE (type) || IS_AGGR_TYPE (TREE_TYPE (index_exp)))
- return build_new_op (ARRAY_REF, LOOKUP_NORMAL,
+ expr = build_new_op (ARRAY_REF, LOOKUP_NORMAL,
array_expr, index_exp, NULL_TREE);
-
- /* Otherwise, create an ARRAY_REF for a pointer or array type. It
- is a little-known fact that, if `a' is an array and `i' is an
- int, you can write `i[a]', which means the same thing as `a[i]'. */
-
- if (TREE_CODE (type) == ARRAY_TYPE)
- p1 = array_expr;
else
- p1 = build_expr_type_conversion (WANT_POINTER, array_expr, false);
+ {
+ tree p1, p2, i1, i2;
+
+ /* Otherwise, create an ARRAY_REF for a pointer or array type.
+ It is a little-known fact that, if `a' is an array and `i' is
+ an int, you can write `i[a]', which means the same thing as
+ `a[i]'. */
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ p1 = array_expr;
+ else
+ p1 = build_expr_type_conversion (WANT_POINTER, array_expr, false);
- if (TREE_CODE (TREE_TYPE (index_exp)) == ARRAY_TYPE)
- p2 = index_exp;
- else
- p2 = build_expr_type_conversion (WANT_POINTER, index_exp, false);
+ if (TREE_CODE (TREE_TYPE (index_exp)) == ARRAY_TYPE)
+ p2 = index_exp;
+ else
+ p2 = build_expr_type_conversion (WANT_POINTER, index_exp, false);
- i1 = build_expr_type_conversion (WANT_INT | WANT_ENUM, array_expr, false);
- i2 = build_expr_type_conversion (WANT_INT | WANT_ENUM, index_exp, false);
+ i1 = build_expr_type_conversion (WANT_INT | WANT_ENUM, array_expr,
+ false);
+ i2 = build_expr_type_conversion (WANT_INT | WANT_ENUM, index_exp,
+ false);
- if ((p1 && i2) && (i1 && p2))
- error ("ambiguous conversion for array subscript");
+ if ((p1 && i2) && (i1 && p2))
+ error ("ambiguous conversion for array subscript");
- if (p1 && i2)
- array_expr = p1, index_exp = i2;
- else if (i1 && p2)
- array_expr = p2, index_exp = i1;
- else
- {
- error ("invalid types `%T[%T]' for array subscript",
- type, TREE_TYPE (index_exp));
- return error_mark_node;
- }
+ if (p1 && i2)
+ array_expr = p1, index_exp = i2;
+ else if (i1 && p2)
+ array_expr = p2, index_exp = i1;
+ else
+ {
+ error ("invalid types `%T[%T]' for array subscript",
+ type, TREE_TYPE (index_exp));
+ return error_mark_node;
+ }
- if (array_expr == error_mark_node || index_exp == error_mark_node)
- error ("ambiguous conversion for array subscript");
+ if (array_expr == error_mark_node || index_exp == error_mark_node)
+ error ("ambiguous conversion for array subscript");
- return build_array_ref (array_expr, index_exp);
+ expr = build_array_ref (array_expr, index_exp);
+ }
+ if (processing_template_decl && expr != error_mark_node)
+ return build_min (ARRAY_REF, TREE_TYPE (expr), orig_array_expr,
+ orig_index_exp);
+ return expr;
}
/* Given the cast expression EXP, checking out its validity. Either return
@@ -2949,8 +2967,37 @@ tree
build_offset_ref_call_from_tree (tree fn, tree args)
{
tree object_addr;
+ tree orig_fn;
+ tree orig_args;
+ tree expr;
+
+ orig_fn = fn;
+ orig_args = args;
- my_friendly_assert (TREE_CODE (fn) == OFFSET_REF, 20020725);
+ if (processing_template_decl)
+ {
+ tree object;
+ tree object_type;
+
+ my_friendly_assert (TREE_CODE (fn) == DOTSTAR_EXPR
+ || TREE_CODE (fn) == MEMBER_REF,
+ 20030708);
+ if (type_dependent_expression_p (fn)
+ || any_type_dependent_arguments_p (args))
+ return build_min_nt (CALL_EXPR, fn, args);
+
+ /* Transform the arguments and add the implicit "this"
+ parameter. That must be done before the FN is transformed
+ because we depend on the form of FN. */
+ args = build_non_dependent_args (args);
+ object_type = TREE_TYPE (TREE_OPERAND (fn, 0));
+ if (TREE_CODE (fn) == DOTSTAR_EXPR)
+ object_type = build_pointer_type (non_reference (object_type));
+ object = build (NON_DEPENDENT_EXPR, object_type);
+ args = tree_cons (NULL_TREE, object, args);
+ /* Now that the arguments are done, transform FN. */
+ fn = build_non_dependent_expr (fn);
+ }
/* A qualified name corresponding to a bound pointer-to-member is
represented as an OFFSET_REF:
@@ -2958,79 +3005,18 @@ build_offset_ref_call_from_tree (tree fn, tree args)
struct B { void g(); };
void (B::*p)();
void B::g() { (this->*p)(); } */
- if (TREE_CODE (TREE_OPERAND (fn, 1)) == FIELD_DECL)
- /* This case should now be handled elsewhere. */
- abort ();
- else
+ if (TREE_CODE (fn) == OFFSET_REF)
{
object_addr = build_unary_op (ADDR_EXPR, TREE_OPERAND (fn, 0), 0);
fn = TREE_OPERAND (fn, 1);
fn = get_member_function_from_ptrfunc (&object_addr, fn);
args = tree_cons (NULL_TREE, object_addr, args);
}
- return build_function_call (fn, args);
-}
-
-/* FN indicates the function to call. Name resolution has been
- performed on FN. ARGS are the arguments to the function. They
- have already been semantically analyzed. DISALLOW_VIRTUAL is true
- if the function call should be determined at compile time, even if
- FN is virtual. */
-
-tree
-build_call_from_tree (tree fn, tree args, bool disallow_virtual)
-{
- tree template_args;
- tree template_id;
- tree f;
-
- /* Check to see that name lookup has already been performed. */
- my_friendly_assert (TREE_CODE (fn) != OFFSET_REF, 20020725);
- my_friendly_assert (TREE_CODE (fn) != SCOPE_REF, 20020725);
-
- /* In the future all of this should be eliminated. Instead,
- name-lookup for a member function should simply return a
- baselink, instead of a FUNCTION_DECL, TEMPLATE_DECL, or
- TEMPLATE_ID_EXPR. */
-
- if (TREE_CODE (fn) == TEMPLATE_ID_EXPR)
- {
- template_id = fn;
- template_args = TREE_OPERAND (fn, 1);
- fn = TREE_OPERAND (fn, 0);
- }
- else
- {
- template_id = NULL_TREE;
- template_args = NULL_TREE;
- }
-
- f = (TREE_CODE (fn) == OVERLOAD) ? get_first_fn (fn) : fn;
- /* Make sure we have a baselink (rather than simply a
- FUNCTION_DECL) for a member function. */
- if (current_class_type
- && ((TREE_CODE (f) == FUNCTION_DECL
- && DECL_FUNCTION_MEMBER_P (f))
- || (DECL_FUNCTION_TEMPLATE_P (f)
- && DECL_FUNCTION_MEMBER_P (f))))
- {
- f = lookup_member (current_class_type, DECL_NAME (f),
- /*protect=*/1, /*want_type=*/false);
- if (f)
- fn = f;
- }
-
- if (template_id)
- {
- if (BASELINK_P (fn))
- BASELINK_FUNCTIONS (fn) = build_nt (TEMPLATE_ID_EXPR,
- BASELINK_FUNCTIONS (fn),
- template_args);
- else
- fn = template_id;
- }
- return finish_call_expr (fn, args, disallow_virtual);
+ expr = build_function_call (fn, args);
+ if (processing_template_decl && expr != error_mark_node)
+ return build_min (CALL_EXPR, TREE_TYPE (expr), orig_fn, orig_args);
+ return expr;
}
/* Returns true if ROOT (a namespace, class, or function) encloses