From 2adeacc9b5d8a9e6b2fe2c328b914df559b65907 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Fri, 6 Aug 1999 18:20:27 +0000 Subject: [PATCH] error.c (dump_expr): Handle EXACT_DIV_EXPR. * error.c (dump_expr): Handle EXACT_DIV_EXPR. (dump_binary_op): Bulletproof. * lex.c (init_parse): Set opname_tab[EXACT_DIV_EXPR]. * tree.c (search_tree): Don't enumerate all the nodes of classes `1', `2', and `<'; handle them generically. Don't be sorry about "unrecognized tree codes"; just abort. (no_linkage_check): Don't do linkage checks for templates. * tree.c (cp_build_qualified_type_real): Handle pointer-to-member-function types correctly. From-SVN: r28550 --- gcc/cp/ChangeLog | 13 +++ gcc/cp/error.c | 6 +- gcc/cp/lex.c | 1 + gcc/cp/tree.c | 102 +++++++++--------- .../g++.old-deja/g++.other/defarg3.C | 9 ++ gcc/testsuite/g++.old-deja/g++.pt/ptrmem8.C | 18 ++++ 6 files changed, 99 insertions(+), 50 deletions(-) create mode 100644 gcc/testsuite/g++.old-deja/g++.other/defarg3.C create mode 100644 gcc/testsuite/g++.old-deja/g++.pt/ptrmem8.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 19fe82d1dc9..aaa8ecfa2c4 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,16 @@ +1999-08-06 Mark Mitchell + + * error.c (dump_expr): Handle EXACT_DIV_EXPR. + (dump_binary_op): Bulletproof. + * lex.c (init_parse): Set opname_tab[EXACT_DIV_EXPR]. + * tree.c (search_tree): Don't enumerate all the nodes of classes + `1', `2', and `<'; handle them generically. Don't be sorry about + "unrecognized tree codes"; just abort. + (no_linkage_check): Don't do linkage checks for templates. + + * tree.c (cp_build_qualified_type_real): Handle + pointer-to-member-function types correctly. + 1999-08-05 Jason Merrill * decl.c (pushdecl): Only give an error for shadowing a parm diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 22be2017804..c455e812367 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -1521,6 +1521,7 @@ dump_expr (t, nop) case GE_EXPR: case EQ_EXPR: case NE_EXPR: + case EXACT_DIV_EXPR: dump_binary_op (opname_tab[(int) TREE_CODE (t)], t); break; @@ -1847,7 +1848,10 @@ dump_binary_op (opstring, t) OB_PUTC ('('); dump_expr (TREE_OPERAND (t, 0), 1); OB_PUTC (' '); - OB_PUTCP (opstring); + if (opstring) + OB_PUTCP (opstring); + else + OB_PUTS (""); OB_PUTC (' '); dump_expr (TREE_OPERAND (t, 1), 1); OB_PUTC (')'); diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index 1bcb667b092..5afda551edf 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -761,6 +761,7 @@ init_parse (filename) opname_tab[(int) CEIL_MOD_EXPR] = "(ceiling %)"; opname_tab[(int) FLOOR_MOD_EXPR] = "(floor %)"; opname_tab[(int) ROUND_MOD_EXPR] = "(round %)"; + opname_tab[(int) EXACT_DIV_EXPR] = "/"; opname_tab[(int) NEGATE_EXPR] = "-"; opname_tab[(int) MIN_EXPR] = "?"; diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index f40632afc33..7b5c16d67de 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -503,6 +503,8 @@ cp_build_qualified_type_real (type, type_quals, complain) int type_quals; int complain; { + tree result; + if (type == error_mark_node) return type; @@ -571,7 +573,32 @@ cp_build_qualified_type_real (type, type_quals, complain) = TYPE_NEEDS_DESTRUCTOR (TYPE_MAIN_VARIANT (element_type)); return t; } - return build_qualified_type (type, type_quals); + else if (TYPE_PTRMEMFUNC_P (type)) + { + /* For a pointer-to-member type, we can't just return a + cv-qualified version of the RECORD_TYPE. If we do, we + haven't change the field that contains the actual pointer to + a method, and so TYPE_PTRMEMFUNC_FN_TYPE will be wrong. */ + tree t; + + t = TYPE_PTRMEMFUNC_FN_TYPE (type); + t = cp_build_qualified_type_real (t, type_quals, complain); + return build_ptrmemfunc_type (t); + } + + /* Retrieve (or create) the appropriately qualified variant. */ + result = build_qualified_type (type, type_quals); + + /* If this was a pointer-to-method type, and we just made a copy, + then we need to clear the cached associated + pointer-to-member-function type; it is not valid for the new + type. */ + if (result != type + && TREE_CODE (type) == POINTER_TYPE + && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE) + TYPE_SET_PTRMEMFUNC_TYPE (result, NULL_TREE); + + return result; } /* Returns the canonical version of TYPE. In other words, if TYPE is @@ -1540,14 +1567,30 @@ search_tree (t, func) #define TRY(ARG) if (tmp=search_tree (ARG, func), tmp != NULL_TREE) return tmp tree tmp; + enum tree_code code; if (t == NULL_TREE) return t; - - if (tmp = func (t), tmp != NULL_TREE) + + tmp = func (t); + if (tmp) return tmp; - switch (TREE_CODE (t)) + /* Handle some common cases up front. */ + code = TREE_CODE (t); + if (TREE_CODE_CLASS (code) == '1') + { + TRY (TREE_OPERAND (t, 0)); + return NULL_TREE; + } + else if (TREE_CODE_CLASS (code) == '2' || TREE_CODE_CLASS (code) == '<') + { + TRY (TREE_OPERAND (t, 0)); + TRY (TREE_OPERAND (t, 1)); + return NULL_TREE; + } + + switch (code) { case ERROR_MARK: break; @@ -1611,35 +1654,8 @@ search_tree (t, func) TRY (TREE_OPERAND (t, 2)); break; - case MODIFY_EXPR: - case PLUS_EXPR: - case MINUS_EXPR: - case MULT_EXPR: - case TRUNC_DIV_EXPR: - case TRUNC_MOD_EXPR: - case MIN_EXPR: - case MAX_EXPR: - case LSHIFT_EXPR: - case RSHIFT_EXPR: - case BIT_IOR_EXPR: - case BIT_XOR_EXPR: - case BIT_AND_EXPR: - case BIT_ANDTC_EXPR: case TRUTH_ANDIF_EXPR: case TRUTH_ORIF_EXPR: - case LT_EXPR: - case LE_EXPR: - case GT_EXPR: - case GE_EXPR: - case EQ_EXPR: - case NE_EXPR: - case CEIL_DIV_EXPR: - case FLOOR_DIV_EXPR: - case ROUND_DIV_EXPR: - case CEIL_MOD_EXPR: - case FLOOR_MOD_EXPR: - case ROUND_MOD_EXPR: - case COMPOUND_EXPR: case PREDECREMENT_EXPR: case PREINCREMENT_EXPR: case POSTDECREMENT_EXPR: @@ -1654,28 +1670,16 @@ search_tree (t, func) break; case SAVE_EXPR: - case CONVERT_EXPR: case ADDR_EXPR: case INDIRECT_REF: - case NEGATE_EXPR: - case BIT_NOT_EXPR: case TRUTH_NOT_EXPR: - case NOP_EXPR: - case NON_LVALUE_EXPR: case COMPONENT_REF: case CLEANUP_POINT_EXPR: case LOOKUP_EXPR: - case SIZEOF_EXPR: - case ALIGNOF_EXPR: TRY (TREE_OPERAND (t, 0)); break; case MODOP_EXPR: - case CAST_EXPR: - case REINTERPRET_CAST_EXPR: - case CONST_CAST_EXPR: - case STATIC_CAST_EXPR: - case DYNAMIC_CAST_EXPR: case ARROW_EXPR: case DOTSTAR_EXPR: case TYPEID_EXPR: @@ -1738,13 +1742,8 @@ search_tree (t, func) TRY (TYPE_PTRMEMFUNC_FN_TYPE (t)); break; - /* This list is incomplete, but should suffice for now. - It is very important that `sorry' not call - `report_error_function'. That could cause an infinite loop. */ default: - sorry ("initializer contains unrecognized tree code"); - return error_mark_node; - + my_friendly_abort (19990803); } return NULL_TREE; @@ -1773,6 +1772,11 @@ tree no_linkage_check (t) tree t; { + /* There's no point in checking linkage on template functions; we + can't know their complete types. */ + if (processing_template_decl) + return NULL_TREE; + t = search_tree (t, no_linkage_helper); if (t != error_mark_node) return t; diff --git a/gcc/testsuite/g++.old-deja/g++.other/defarg3.C b/gcc/testsuite/g++.old-deja/g++.other/defarg3.C new file mode 100644 index 00000000000..84792c8c4c1 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/defarg3.C @@ -0,0 +1,9 @@ +// Build don't link: +// Origin: Mark Mitchell + +int* hp; +int* jp; + +void f (int *ip, int kp = hp - jp) +{ +} diff --git a/gcc/testsuite/g++.old-deja/g++.pt/ptrmem8.C b/gcc/testsuite/g++.old-deja/g++.pt/ptrmem8.C new file mode 100644 index 00000000000..f6125cdeaf6 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/ptrmem8.C @@ -0,0 +1,18 @@ +// Build don't link: +// Origin: Mark Mitchell + +template +struct S +{ + void f (const T&); + void f (T&); +}; + +class C +{ +}; + +typedef int (C::*cp)(); + +template struct S; +