This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH to fix --enable-checking problems
- To: gcc-patches at gcc dot gnu dot org
- Subject: C++ PATCH to fix --enable-checking problems
- From: Mark Mitchell <mark at codesourcery dot com>
- Date: Wed, 12 Jan 2000 15:28:30 -0800
- Organization: CodeSourcery, LLC
This patch fixes most of the problems revealed by running the C++
testsuite with --enable-checking. We had an overactive check or two,
a bunch of cases where errors lead to subsequent crashes, and a few
cases where non-erroneous programs could lead to bizarre behavior.
Once again, kudos are due to the folks who implemented the
tree-checking.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
2000-01-12 Mark Mitchell <mark@codesourcery.com>
* call.c (convert_class_to_reference): Fix typos.
(build_conditional_expr): Handle errors gracefully.
* class.c (push_nested_class): Likewise.
* cp-tree.h (VAR_FUNCTION_OR_PARM_DECL_CHECK): New macro.
(DECL_THIS_EXTERN): Use it.
(DECL_THIS_STATIC): Likewise.
* cvt.c (convert_to_void): Handle errors gracefully.
(build_expr_type_conversion): Likewise.
* decl.c (maybe_push_decl): Likewise.
(start_decl_1): Likewise.
(require_complete_types_for_parms): Likewise.
* parse.y (structsp): Likewise.
(base_class): Likewise.
* parse.c: Regenerated.
* pt.c (finish_member_template_decl): Likewise.
Index: call.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/call.c,v
retrieving revision 1.185
diff -c -p -r1.185 call.c
*** call.c 2000/01/01 13:29:44 1.185
--- call.c 2000/01/12 23:19:57
*************** convert_class_to_reference (t, s, expr)
*** 928,937 ****
if (!cand)
return NULL_TREE;
! conv = build_conv (IDENTITY_CONV, s, expr);
conv = build_conv (USER_CONV,
non_reference (TREE_TYPE (TREE_TYPE (cand->fn))),
! expr);
TREE_OPERAND (conv, 1) = build_expr_ptr_wrapper (cand);
ICS_USER_FLAG (conv) = 1;
if (cand->viable == -1)
--- 928,937 ----
if (!cand)
return NULL_TREE;
! conv = build1 (IDENTITY_CONV, s, expr);
conv = build_conv (USER_CONV,
non_reference (TREE_TYPE (TREE_TYPE (cand->fn))),
! conv);
TREE_OPERAND (conv, 1) = build_expr_ptr_wrapper (cand);
ICS_USER_FLAG (conv) = 1;
if (cand->viable == -1)
*************** build_conditional_expr (arg1, arg2, arg3
*** 2770,2775 ****
--- 2770,2781 ----
arg1 = arg2 = save_expr (arg1);
}
+ /* [expr.cond]
+
+ The first expr ession is implicitly converted to bool (clause
+ _conv_). */
+ arg1 = cp_convert (boolean_type_node, arg1);
+
/* If something has already gone wrong, just pass that fact up the
tree. */
if (arg1 == error_mark_node
*************** build_conditional_expr (arg1, arg2, arg3
*** 2779,2790 ****
|| TREE_TYPE (arg2) == error_mark_node
|| TREE_TYPE (arg3) == error_mark_node)
return error_mark_node;
-
- /* [expr.cond]
-
- The first expr ession is implicitly converted to bool (clause
- _conv_). */
- arg1 = cp_convert (boolean_type_node, arg1);
/* Convert from reference types to ordinary types; no expressions
really have reference type in C++. */
--- 2785,2790 ----
Index: class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.230
diff -c -p -r1.230 class.c
*** class.c 2000/01/12 20:56:15 1.230
--- class.c 2000/01/12 23:20:01
*************** push_nested_class (type, modify)
*** 5279,5286 ****
tree context;
/* A namespace might be passed in error cases, like A::B:C. */
! if (type == NULL_TREE || type == error_mark_node || ! IS_AGGR_TYPE (type)
|| TREE_CODE (type) == NAMESPACE_DECL
|| TREE_CODE (type) == TEMPLATE_TYPE_PARM
|| TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM)
return;
--- 5279,5288 ----
tree context;
/* A namespace might be passed in error cases, like A::B:C. */
! if (type == NULL_TREE
! || type == error_mark_node
|| TREE_CODE (type) == NAMESPACE_DECL
+ || ! IS_AGGR_TYPE (type)
|| TREE_CODE (type) == TEMPLATE_TYPE_PARM
|| TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM)
return;
Index: cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.382
diff -c -p -r1.382 cp-tree.h
*** cp-tree.h 2000/01/12 20:56:15 1.382
--- cp-tree.h 2000/01/12 23:20:04
*************** Boston, MA 02111-1307, USA. */
*** 140,145 ****
--- 140,155 ----
__LINE__, __PRETTY_FUNCTION__); \
__t; })
+ #define VAR_FUNCTION_OR_PARM_DECL_CHECK(NODE) \
+ ({ const tree __t = NODE; \
+ enum tree_code __c = TREE_CODE(__t); \
+ if (__c != VAR_DECL \
+ && __c != FUNCTION_DECL \
+ && __c != PARM_DECL) \
+ tree_check_failed (__t, VAR_DECL, __FILE__, \
+ __LINE__, __PRETTY_FUNCTION__); \
+ __t; })
+
#define VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK(NODE) \
({ const tree __t = NODE; \
enum tree_code __c = TREE_CODE(__t); \
*************** Boston, MA 02111-1307, USA. */
*** 162,167 ****
--- 172,178 ----
#else /* not ENABLE_TREE_CHECKING, or not gcc */
#define VAR_OR_FUNCTION_DECL_CHECK(NODE) NODE
+ #define VAR_FUNCTION_OR_PARM_DECL_CHECK(NODE) NODE
#define VAR_TEMPL_TYPE_OR_FUNCTION_DECL_CHECK(NODE) NODE
#define RECORD_OR_UNION_TYPE_CHECK(NODE) NODE
*************** extern int flag_new_for_scope;
*** 2380,2393 ****
#define PTRMEM_CST_MEMBER(NODE) (((ptrmem_cst_t)PTRMEM_CST_CHECK (NODE))->member)
/* Nonzero for VAR_DECL and FUNCTION_DECL node means that `extern' was
! specified in its declaration. */
#define DECL_THIS_EXTERN(NODE) \
! DECL_LANG_FLAG_2 (VAR_OR_FUNCTION_DECL_CHECK (NODE))
/* Nonzero for VAR_DECL and FUNCTION_DECL node means that `static' was
! specified in its declaration. */
#define DECL_THIS_STATIC(NODE) \
! DECL_LANG_FLAG_6 (VAR_OR_FUNCTION_DECL_CHECK (NODE))
/* Nonzero in FUNCTION_DECL means it is really an operator.
Just used to communicate formatting information to dbxout.c. */
--- 2391,2406 ----
#define PTRMEM_CST_MEMBER(NODE) (((ptrmem_cst_t)PTRMEM_CST_CHECK (NODE))->member)
/* Nonzero for VAR_DECL and FUNCTION_DECL node means that `extern' was
! specified in its declaration. This can also be set for an
! erroneously declared PARM_DECL. */
#define DECL_THIS_EXTERN(NODE) \
! DECL_LANG_FLAG_2 (VAR_FUNCTION_OR_PARM_DECL_CHECK (NODE))
/* Nonzero for VAR_DECL and FUNCTION_DECL node means that `static' was
! specified in its declaration. This can also be set for an
! erroneously declared PARM_DECL. */
#define DECL_THIS_STATIC(NODE) \
! DECL_LANG_FLAG_6 (VAR_FUNCTION_OR_PARM_DECL_CHECK (NODE))
/* Nonzero in FUNCTION_DECL means it is really an operator.
Just used to communicate formatting information to dbxout.c. */
Index: cvt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cvt.c,v
retrieving revision 1.71
diff -c -p -r1.71 cvt.c
*** cvt.c 1999/11/14 20:29:02 1.71
--- cvt.c 2000/01/12 23:20:04
***************
*** 1,5 ****
/* Language-level data type conversion for GNU C++.
! Copyright (C) 1987-1988, 1992-1999 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
--- 1,5 ----
/* Language-level data type conversion for GNU C++.
! Copyright (C) 1987-1988, 1992-2000 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
*************** convert_to_void (expr, implicit)
*** 851,858 ****
tree expr;
const char *implicit;
{
! if (expr == error_mark_node)
! return expr;
if (!TREE_TYPE (expr))
return expr;
if (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)), void_type_node))
--- 851,859 ----
tree expr;
const char *implicit;
{
! if (expr == error_mark_node
! || TREE_TYPE (expr) == error_mark_node)
! return error_mark_node;
if (!TREE_TYPE (expr))
return expr;
if (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (expr)), void_type_node))
*************** build_expr_type_conversion (desires, exp
*** 1091,1096 ****
--- 1092,1100 ----
expr = resolve_offset_ref (expr);
expr = convert_from_reference (expr);
basetype = TREE_TYPE (expr);
+
+ if (basetype == error_mark_node)
+ return error_mark_node;
if (! IS_AGGR_TYPE (basetype))
switch (TREE_CODE (basetype))
Index: decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.529
diff -c -p -r1.529 decl.c
*** decl.c 2000/01/03 21:33:10 1.529
--- decl.c 2000/01/12 23:20:14
***************
*** 1,5 ****
/* Process declarations and variables for C compiler.
! Copyright (C) 1988, 92-98, 1999 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
--- 1,5 ----
/* Process declarations and variables for C compiler.
! Copyright (C) 1988, 92-98, 1999, 2000 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
*************** maybe_push_decl (decl)
*** 4169,4179 ****
/* Add this decl to the current binding level, but not if it comes
from another scope, e.g. a static member variable. TEM may equal
DECL or it may be a previous decl of the same name. */
! if ((TREE_CODE (decl) != PARM_DECL
! && DECL_CONTEXT (decl) != NULL_TREE
! /* Definitions of namespace members outside their namespace are
! possible. */
! && TREE_CODE (DECL_CONTEXT (decl)) != NAMESPACE_DECL)
|| (TREE_CODE (decl) == TEMPLATE_DECL && !namespace_bindings_p ())
|| TREE_CODE (type) == UNKNOWN_TYPE
/* The declaration of a template specialization does not affect
--- 4169,4180 ----
/* Add this decl to the current binding level, but not if it comes
from another scope, e.g. a static member variable. TEM may equal
DECL or it may be a previous decl of the same name. */
! if (decl == error_mark_node
! || (TREE_CODE (decl) != PARM_DECL
! && DECL_CONTEXT (decl) != NULL_TREE
! /* Definitions of namespace members outside their namespace are
! possible. */
! && TREE_CODE (DECL_CONTEXT (decl)) != NAMESPACE_DECL)
|| (TREE_CODE (decl) == TEMPLATE_DECL && !namespace_bindings_p ())
|| TREE_CODE (type) == UNKNOWN_TYPE
/* The declaration of a template specialization does not affect
*************** start_decl_1 (decl)
*** 6871,6877 ****
if (!initialized
&& TREE_CODE (decl) != TYPE_DECL
&& TREE_CODE (decl) != TEMPLATE_DECL
! && IS_AGGR_TYPE (type) && ! DECL_EXTERNAL (decl))
{
if ((! processing_template_decl || ! uses_template_parms (type))
&& TYPE_SIZE (complete_type (type)) == NULL_TREE)
--- 6872,6880 ----
if (!initialized
&& TREE_CODE (decl) != TYPE_DECL
&& TREE_CODE (decl) != TEMPLATE_DECL
! && type != error_mark_node
! && IS_AGGR_TYPE (type)
! && ! DECL_EXTERNAL (decl))
{
if ((! processing_template_decl || ! uses_template_parms (type))
&& TYPE_SIZE (complete_type (type)) == NULL_TREE)
*************** static void
*** 11309,11318 ****
require_complete_types_for_parms (parms)
tree parms;
{
! while (parms)
{
tree type = TREE_TYPE (parms);
! if (TYPE_SIZE (complete_type (type)) == NULL_TREE)
{
if (DECL_NAME (parms))
error ("parameter `%s' has incomplete type",
--- 11312,11328 ----
require_complete_types_for_parms (parms)
tree parms;
{
! for (; parms; parms = TREE_CHAIN (parms))
{
tree type = TREE_TYPE (parms);
!
! /* Try to complete the TYPE. */
! type = complete_type (type);
!
! if (type == error_mark_node)
! continue;
!
! if (TYPE_SIZE (type) == NULL_TREE)
{
if (DECL_NAME (parms))
error ("parameter `%s' has incomplete type",
*************** require_complete_types_for_parms (parms)
*** 11323,11330 ****
}
else
layout_decl (parms, 0);
-
- parms = TREE_CHAIN (parms);
}
}
--- 11333,11338 ----
Index: parse.y
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/parse.y,v
retrieving revision 1.156
diff -c -p -r1.156 parse.y
*** parse.y 1999/11/16 03:42:26 1.156
--- parse.y 2000/01/12 23:20:26
***************
*** 1,5 ****
/* YACC parser for C++ syntax.
! Copyright (C) 1988, 89, 93-98, 1999 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
--- 1,5 ----
/* YACC parser for C++ syntax.
! Copyright (C) 1988, 89, 93-98, 1999, 2000 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@cygnus.com)
This file is part of GNU CC.
*************** structsp:
*** 2124,2130 ****
{
$$.t = $1.t;
/* struct B: public A; is not accepted by the WP grammar. */
! if (TYPE_BINFO_BASETYPES ($$.t) && !TYPE_SIZE ($$.t)
&& ! TYPE_BEING_DEFINED ($$.t))
cp_error ("base clause without member specification for `%#T'",
$$.t);
--- 2124,2132 ----
{
$$.t = $1.t;
/* struct B: public A; is not accepted by the WP grammar. */
! if (CLASS_TYPE_P ($$.t)
! && TYPE_BINFO_BASETYPES ($$.t)
! && !TYPE_SIZE ($$.t)
&& ! TYPE_BEING_DEFINED ($$.t))
cp_error ("base clause without member specification for `%#T'",
$$.t);
*************** base_class:
*** 2298,2304 ****
base_class.1:
typename_sub
! { if ($$ != error_mark_node) $$ = TYPE_MAIN_DECL ($1); }
| nonnested_type
;
--- 2300,2311 ----
base_class.1:
typename_sub
! { if ($$ == error_mark_node)
! ;
! else if (!TYPE_P ($$))
! $$ = error_mark_node;
! else
! $$ = TYPE_MAIN_DECL ($1); }
| nonnested_type
;
Index: pt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/pt.c,v
retrieving revision 1.390
diff -c -p -r1.390 pt.c
*** pt.c 2000/01/07 07:06:59 1.390
--- pt.c 2000/01/12 23:20:33
***************
*** 1,5 ****
/* Handle parameterized types (templates) for GNU C++.
! Copyright (C) 1992, 93-97, 1998, 1999 Free Software Foundation, Inc.
Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
Rewritten by Jason Merrill (jason@cygnus.com).
--- 1,5 ----
/* Handle parameterized types (templates) for GNU C++.
! Copyright (C) 1992, 93-97, 1998, 1999, 2000 Free Software Foundation, Inc.
Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
Rewritten by Jason Merrill (jason@cygnus.com).
*************** finish_member_template_decl (decl)
*** 197,202 ****
--- 197,204 ----
}
return NULL_TREE;
}
+ else if (TREE_CODE (decl) == FIELD_DECL)
+ cp_error ("data member `%D' cannot be a member template", decl);
else if (DECL_TEMPLATE_INFO (decl))
{
if (!DECL_TEMPLATE_SPECIALIZATION (decl))
*************** tsubst (t, args, complain, in_decl)
*** 6214,6220 ****
if (pedantic)
pedwarn ("creating array with size zero");
}
! else if (integer_zerop (max) || INT_CST_LT (max, integer_zero_node))
{
/* [temp.deduct]
--- 6216,6224 ----
if (pedantic)
pedwarn ("creating array with size zero");
}
! else if (integer_zerop (max)
! || (TREE_CODE (max) == INTEGER_CST
! && INT_CST_LT (max, integer_zero_node)))
{
/* [temp.deduct]
Index: typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/typeck.c,v
retrieving revision 1.234
diff -c -p -r1.234 typeck.c
*** typeck.c 2000/01/05 10:10:53 1.234
--- typeck.c 2000/01/12 23:20:39
*************** decay_conversion (exp)
*** 1705,1710 ****
--- 1705,1713 ----
code = TREE_CODE (type);
}
+ if (type == error_mark_node)
+ return error_mark_node;
+
/* Constants can be used directly unless they're not loadable. */
if (TREE_CODE (exp) == CONST_DECL)
exp = DECL_INITIAL (exp);