C++ PATCH: Cleanup for decl_constant_value

Mark Mitchell mark@codesourcery.com
Wed Apr 26 08:40:00 GMT 2000


The protocol for calling decl_constant_value was that you had to check
TREE_READONLY_DECL_P before the call.  That wasn't documented, and
it's confusing, and it's error-prone.  This patch pushes the check
into the function itself, making it safe to call decl_constant_value
without the check.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

2000-04-26  Mark Mitchell  <mark@codesourcery.com>

	* cp-tree.h (TREE_READONLY_DECL_P): Use DECL_P.
	* init.c (decl_constant_value): Check TREE_READONLY_DECL_P.
	* call.c (convert_like_real): Don't test TREE_READONLY_DECL_P
	before calling decl_constant_value.
	* class.c (check_bitfield_decl): Likewise.
	* cvt.c (ocp_convert): Likewise.
	(convert): Likewise.
	* decl.c (compute_array_index_type): Likewise.
	(build_enumerator): Likewise.
	* decl2.c (check_cp_case_value): Likewise.
	* pt.c (convert_nontype_argument): Likewise.
	(tsubst): Likewise.
	* typeck.c (decay_conversion): Likewise.
	(build_compound_expr): Likewise.
	(build_reinterpret_cast): Likewise.
	(build_c_cast): Likewise.
	(convert_for_assignment): Likewise.
	
Index: call.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/call.c,v
retrieving revision 1.211
diff -c -p -r1.211 call.c
*** call.c	2000/04/20 05:53:57	1.211
--- call.c	2000/04/26 15:33:35
*************** convert_like_real (convs, expr, fn, argn
*** 3700,3706 ****
    /* Convert a non-array constant variable to its underlying value, unless we
       are about to bind it to a reference, in which case we need to
       leave it as an lvalue.  */
!   if (TREE_READONLY_DECL_P (expr) && TREE_CODE (convs) != REF_BIND
        && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
      expr = decl_constant_value (expr);
  
--- 3700,3706 ----
    /* Convert a non-array constant variable to its underlying value, unless we
       are about to bind it to a reference, in which case we need to
       leave it as an lvalue.  */
!   if (TREE_CODE (convs) != REF_BIND
        && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE)
      expr = decl_constant_value (expr);
  
Index: class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.295
diff -c -p -r1.295 class.c
*** class.c	2000/04/18 20:21:38	1.295
--- class.c	2000/04/26 15:33:39
*************** check_bitfield_decl (field)
*** 3061,3067 ****
        /* detect invalid field size.  */
        if (TREE_CODE (w) == CONST_DECL)
  	w = DECL_INITIAL (w);
!       else if (TREE_READONLY_DECL_P (w))
  	w = decl_constant_value (w);
  
        if (TREE_CODE (w) != INTEGER_CST)
--- 3061,3067 ----
        /* detect invalid field size.  */
        if (TREE_CODE (w) == CONST_DECL)
  	w = DECL_INITIAL (w);
!       else
  	w = decl_constant_value (w);
  
        if (TREE_CODE (w) != INTEGER_CST)
Index: cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.445
diff -c -p -r1.445 cp-tree.h
*** cp-tree.h	2000/04/24 06:41:15	1.445
--- cp-tree.h	2000/04/26 15:33:43
*************** struct lang_decl
*** 1926,1932 ****
  
  /* Non-zero if NODE is a _DECL with TREE_READONLY set.  */
  #define TREE_READONLY_DECL_P(NODE) \
!   (TREE_READONLY (NODE) && TREE_CODE_CLASS (TREE_CODE (NODE)) == 'd')
  
  /* Non-zero iff DECL is memory-based.  The DECL_RTL of
     certain const variables might be a CONST_INT, or a REG
--- 1926,1932 ----
  
  /* Non-zero if NODE is a _DECL with TREE_READONLY set.  */
  #define TREE_READONLY_DECL_P(NODE) \
!   (TREE_READONLY (NODE) && DECL_P (NODE))
  
  /* Non-zero iff DECL is memory-based.  The DECL_RTL of
     certain const variables might be a CONST_INT, or a REG
Index: cvt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cvt.c,v
retrieving revision 1.81
diff -c -p -r1.81 cvt.c
*** cvt.c	2000/04/11 00:38:37	1.81
--- cvt.c	2000/04/26 15:33:44
*************** ocp_convert (type, expr, convtype, flags
*** 673,680 ****
    complete_type (type);
    complete_type (TREE_TYPE (expr));
  
!   if (TREE_READONLY_DECL_P (e))
!     e = decl_constant_value (e);
  
    if (IS_AGGR_TYPE (type) && (convtype & CONV_FORCE_TEMP)
        /* Some internal structures (vtable_entry_type, sigtbl_ptr_type)
--- 673,679 ----
    complete_type (type);
    complete_type (TREE_TYPE (expr));
  
!   e = decl_constant_value (e);
  
    if (IS_AGGR_TYPE (type) && (convtype & CONV_FORCE_TEMP)
        /* Some internal structures (vtable_entry_type, sigtbl_ptr_type)
*************** convert (type, expr)
*** 999,1006 ****
  
    if (POINTER_TYPE_P (type) && POINTER_TYPE_P (intype))
      {
!       if (TREE_READONLY_DECL_P (expr))
! 	expr = decl_constant_value (expr);
        return fold (build1 (NOP_EXPR, type, expr));
      }
  
--- 998,1004 ----
  
    if (POINTER_TYPE_P (type) && POINTER_TYPE_P (intype))
      {
!       expr = decl_constant_value (expr);
        return fold (build1 (NOP_EXPR, type, expr));
      }
  
Index: decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.594
diff -c -p -r1.594 decl.c
*** decl.c	2000/04/24 06:41:16	1.594
--- decl.c	2000/04/26 15:33:53
*************** compute_array_index_type (name, size)
*** 9124,9131 ****
    STRIP_TYPE_NOPS (size);
  
    /* It might be a const variable or enumeration constant.  */
!   if (TREE_READONLY_DECL_P (size))
!     size = decl_constant_value (size);
  
    /* If this involves a template parameter, it will be a constant at
       instantiation time, but we don't know what the value is yet.
--- 9124,9130 ----
    STRIP_TYPE_NOPS (size);
  
    /* It might be a const variable or enumeration constant.  */
!   size = decl_constant_value (size);
  
    /* If this involves a template parameter, it will be a constant at
       instantiation time, but we don't know what the value is yet.
*************** build_enumerator (name, value, enumtype)
*** 13005,13012 ****
        /* Validate and default VALUE.  */
        if (value != NULL_TREE)
  	{
! 	  if (TREE_READONLY_DECL_P (value))
! 	    value = decl_constant_value (value);
  
  	  if (TREE_CODE (value) == INTEGER_CST)
  	    {
--- 13004,13010 ----
        /* Validate and default VALUE.  */
        if (value != NULL_TREE)
  	{
! 	  value = decl_constant_value (value);
  
  	  if (TREE_CODE (value) == INTEGER_CST)
  	    {
Index: decl2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl2.c,v
retrieving revision 1.337
diff -c -p -r1.337 decl2.c
*** decl2.c	2000/04/20 05:53:57	1.337
--- decl2.c	2000/04/26 15:33:56
*************** check_cp_case_value (value)
*** 4148,4159 ****
  
    /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
    STRIP_TYPE_NOPS (value);
! 
!   if (TREE_READONLY_DECL_P (value))
!     {
!       value = decl_constant_value (value);
!       STRIP_TYPE_NOPS (value);
!     }
    value = fold (value);
  
    if (TREE_CODE (value) != INTEGER_CST
--- 4148,4155 ----
  
    /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */
    STRIP_TYPE_NOPS (value);
!   value = decl_constant_value (value);
!   STRIP_TYPE_NOPS (value);
    value = fold (value);
  
    if (TREE_CODE (value) != INTEGER_CST
Index: init.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/init.c,v
retrieving revision 1.186
diff -c -p -r1.186 init.c
*** init.c	2000/04/12 16:13:43	1.186
--- init.c	2000/04/26 15:33:58
*************** resolve_offset_ref (exp)
*** 1779,1791 ****
    return NULL_TREE;
  }
  
! /* Return either DECL or its known constant value (if it has one).  */
  
  tree
  decl_constant_value (decl)
       tree decl;
  {
!   if (! TREE_THIS_VOLATILE (decl)
        && DECL_INITIAL (decl)
        && DECL_INITIAL (decl) != error_mark_node
        /* This is invalid if initial value is not constant.
--- 1779,1793 ----
    return NULL_TREE;
  }
  
! /* If DECL is a `const' declaration, and its value is a known
!    constant, then return that value.  */
  
  tree
  decl_constant_value (decl)
       tree decl;
  {
!   if (TREE_READONLY_DECL_P (decl)
!       && ! TREE_THIS_VOLATILE (decl)
        && DECL_INITIAL (decl)
        && DECL_INITIAL (decl) != error_mark_node
        /* This is invalid if initial value is not constant.
Index: pt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/pt.c,v
retrieving revision 1.422
diff -c -p -r1.422 pt.c
*** pt.c	2000/04/24 06:41:16	1.422
--- pt.c	2000/04/26 15:34:04
*************** convert_nontype_argument (type, expr)
*** 2701,2707 ****
       enumerators.  Simplify things by folding them to their values,
       unless we're about to bind the declaration to a reference
       parameter.  */
!   if (INTEGRAL_TYPE_P (expr_type) && TREE_READONLY_DECL_P (expr)
        && TREE_CODE (type) != REFERENCE_TYPE)
      expr = decl_constant_value (expr);
  
--- 2701,2707 ----
       enumerators.  Simplify things by folding them to their values,
       unless we're about to bind the declaration to a reference
       parameter.  */
!   if (INTEGRAL_TYPE_P (expr_type)
        && TREE_CODE (type) != REFERENCE_TYPE)
      expr = decl_constant_value (expr);
  
*************** tsubst (t, args, complain, in_decl)
*** 6200,6206 ****
  
  	/* See if we can reduce this expression to something simpler.  */
  	max = maybe_fold_nontype_arg (max);
! 	if (!processing_template_decl && TREE_READONLY_DECL_P (max))
  	  max = decl_constant_value (max);
  
  	if (processing_template_decl 
--- 6200,6206 ----
  
  	/* See if we can reduce this expression to something simpler.  */
  	max = maybe_fold_nontype_arg (max);
! 	if (!processing_template_decl)
  	  max = decl_constant_value (max);
  
  	if (processing_template_decl 
Index: typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/typeck.c,v
retrieving revision 1.280
diff -c -p -r1.280 typeck.c
*** typeck.c	2000/04/23 22:32:18	1.280
--- typeck.c	2000/04/26 15:34:08
*************** decay_conversion (exp)
*** 1710,1716 ****
       don't do this for arrays, though; we want the address of the
       first element of the array, not the address of the first element
       of its initializing constant.  */
!   else if (TREE_READONLY_DECL_P (exp) && code != ARRAY_TYPE)
      {
        exp = decl_constant_value (exp);
        type = TREE_TYPE (exp);
--- 1710,1716 ----
       don't do this for arrays, though; we want the address of the
       first element of the array, not the address of the first element
       of its initializing constant.  */
!   else if (code != ARRAY_TYPE)
      {
        exp = decl_constant_value (exp);
        type = TREE_TYPE (exp);
*************** build_compound_expr (list)
*** 5084,5091 ****
    register tree rest;
    tree first;
  
!   if (TREE_READONLY_DECL_P (TREE_VALUE (list)))
!     TREE_VALUE (list) = decl_constant_value (TREE_VALUE (list));
  
    if (TREE_CHAIN (list) == 0)
      {
--- 5084,5090 ----
    register tree rest;
    tree first;
  
!   TREE_VALUE (list) = decl_constant_value (TREE_VALUE (list));
  
    if (TREE_CHAIN (list) == 0)
      {
*************** build_reinterpret_cast (type, expr)
*** 5272,5279 ****
    else if ((TYPE_PTRFN_P (type) && TYPE_PTRFN_P (intype))
  	   || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
      {
!       if (TREE_READONLY_DECL_P (expr))
! 	expr = decl_constant_value (expr);
        return fold (build1 (NOP_EXPR, type, expr));
      }
    else if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
--- 5271,5277 ----
    else if ((TYPE_PTRFN_P (type) && TYPE_PTRFN_P (intype))
  	   || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)))
      {
!       expr = decl_constant_value (expr);
        return fold (build1 (NOP_EXPR, type, expr));
      }
    else if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype))
*************** build_reinterpret_cast (type, expr)
*** 5283,5298 ****
  	cp_pedwarn ("reinterpret_cast from `%T' to `%T' casts away const (or volatile)",
  		    intype, type);
  
!       if (TREE_READONLY_DECL_P (expr))
! 	expr = decl_constant_value (expr);
        return fold (build1 (NOP_EXPR, type, expr));
      }
    else if ((TYPE_PTRFN_P (type) && TYPE_PTROBV_P (intype))
  	   || (TYPE_PTRFN_P (intype) && TYPE_PTROBV_P (type)))
      {
        pedwarn ("ISO C++ forbids casting between pointer-to-function and pointer-to-object");
!       if (TREE_READONLY_DECL_P (expr))
! 	expr = decl_constant_value (expr);
        return fold (build1 (NOP_EXPR, type, expr));
      }
    else
--- 5281,5294 ----
  	cp_pedwarn ("reinterpret_cast from `%T' to `%T' casts away const (or volatile)",
  		    intype, type);
  
!       expr = decl_constant_value (expr);
        return fold (build1 (NOP_EXPR, type, expr));
      }
    else if ((TYPE_PTRFN_P (type) && TYPE_PTROBV_P (intype))
  	   || (TYPE_PTRFN_P (intype) && TYPE_PTROBV_P (type)))
      {
        pedwarn ("ISO C++ forbids casting between pointer-to-function and pointer-to-object");
!       expr = decl_constant_value (expr);
        return fold (build1 (NOP_EXPR, type, expr));
      }
    else
*************** build_c_cast (type, expr)
*** 5498,5505 ****
      {
        tree ovalue;
  
!       if (TREE_READONLY_DECL_P (value))
! 	value = decl_constant_value (value);
  
        ovalue = value;
        value = convert_force (type, value, CONV_C_CAST);
--- 5494,5500 ----
      {
        tree ovalue;
  
!       value = decl_constant_value (value);
  
        ovalue = value;
        value = convert_force (type, value, CONV_C_CAST);
*************** convert_for_assignment (type, rhs, errty
*** 6493,6499 ****
    /* Simplify the RHS if possible.  */
    if (TREE_CODE (rhs) == CONST_DECL)
      rhs = DECL_INITIAL (rhs);
!   else if (TREE_READONLY_DECL_P (rhs) && coder != ARRAY_TYPE)
      rhs = decl_constant_value (rhs);
  
    /* [expr.ass]
--- 6488,6494 ----
    /* Simplify the RHS if possible.  */
    if (TREE_CODE (rhs) == CONST_DECL)
      rhs = DECL_INITIAL (rhs);
!   else if (coder != ARRAY_TYPE)
      rhs = decl_constant_value (rhs);
  
    /* [expr.ass]


More information about the Gcc-patches mailing list