fix c/17322

Richard Henderson rth@redhat.com
Thu Sep 9 18:06:00 GMT 2004


This seems to do the job.  Joseph reviewed the patch in the PR,
and was of the opinion that if we were to ever do constant 
expressions 100% standards conformant, it would have to be done
elsewhere anyway.


r~


        PR c/17322
        * c-typeck.c (valid_compound_expr_initializer): Use only
        initializer_constant_valid_p, and not TREE_CONSTANT.
        (digest_init): Likewise.
        (output_init_element): Likewise.

Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.368
diff -c -p -d -r1.368 c-typeck.c
*** c-typeck.c	9 Sep 2004 01:19:13 -0000	1.368
--- c-typeck.c	9 Sep 2004 17:29:38 -0000
*************** valid_compound_expr_initializer (tree va
*** 3737,3744 ****
        return valid_compound_expr_initializer (TREE_OPERAND (value, 1),
  					      endtype);
      }
!   else if (! TREE_CONSTANT (value)
! 	   && ! initializer_constant_valid_p (value, endtype))
      return error_mark_node;
    else
      return value;
--- 3737,3743 ----
        return valid_compound_expr_initializer (TREE_OPERAND (value, 1),
  					      endtype);
      }
!   else if (!initializer_constant_valid_p (value, endtype))
      return error_mark_node;
    else
      return value;
*************** digest_init (tree type, tree init, bool 
*** 4166,4181 ****
  	    inside_init = error_mark_node;
  	}
        else if (require_constant
! 	       && (!TREE_CONSTANT (inside_init)
! 		   /* This test catches things like `7 / 0' which
! 		      result in an expression for which TREE_CONSTANT
! 		      is true, but which is not actually something
! 		      that is a legal constant.  We really should not
! 		      be using this function, because it is a part of
! 		      the back-end.  Instead, the expression should
! 		      already have been turned into ERROR_MARK_NODE.  */
! 		   || !initializer_constant_valid_p (inside_init,
! 						     TREE_TYPE (inside_init))))
  	{
  	  error_init ("initializer element is not constant");
  	  inside_init = error_mark_node;
--- 4165,4172 ----
  	    inside_init = error_mark_node;
  	}
        else if (require_constant
! 	       && !initializer_constant_valid_p (inside_init,
! 						 TREE_TYPE (inside_init)))
  	{
  	  error_init ("initializer element is not constant");
  	  inside_init = error_mark_node;
*************** digest_init (tree type, tree init, bool 
*** 4203,4209 ****
  	  inside_init = error_mark_node;
  	}
        else if (require_constant
! 	       && initializer_constant_valid_p (inside_init, TREE_TYPE (inside_init)) == 0)
  	{
  	  error_init ("initializer element is not computable at load time");
  	  inside_init = error_mark_node;
--- 4194,4201 ----
  	  inside_init = error_mark_node;
  	}
        else if (require_constant
! 	       && !initializer_constant_valid_p (inside_init,
! 						 TREE_TYPE (inside_init)))
  	{
  	  error_init ("initializer element is not computable at load time");
  	  inside_init = error_mark_node;
*************** output_init_element (tree value, bool st
*** 5585,5605 ****
      constructor_erroneous = 1;
    else if (!TREE_CONSTANT (value))
      constructor_constant = 0;
!   else if (initializer_constant_valid_p (value, TREE_TYPE (value)) == 0
  	   || ((TREE_CODE (constructor_type) == RECORD_TYPE
  		|| TREE_CODE (constructor_type) == UNION_TYPE)
  	       && DECL_C_BIT_FIELD (field)
  	       && TREE_CODE (value) != INTEGER_CST))
      constructor_simple = 0;
  
!   if (require_constant_value && ! TREE_CONSTANT (value))
      {
!       error_init ("initializer element is not constant");
!       value = error_mark_node;
      }
-   else if (require_constant_elements
- 	   && initializer_constant_valid_p (value, TREE_TYPE (value)) == 0)
-     pedwarn ("initializer element is not computable at load time");
  
    /* If this field is empty (and not at the end of structure),
       don't do anything other than checking the initializer.  */
--- 5577,5599 ----
      constructor_erroneous = 1;
    else if (!TREE_CONSTANT (value))
      constructor_constant = 0;
!   else if (!initializer_constant_valid_p (value, TREE_TYPE (value))
  	   || ((TREE_CODE (constructor_type) == RECORD_TYPE
  		|| TREE_CODE (constructor_type) == UNION_TYPE)
  	       && DECL_C_BIT_FIELD (field)
  	       && TREE_CODE (value) != INTEGER_CST))
      constructor_simple = 0;
  
!   if (!initializer_constant_valid_p (value, TREE_TYPE (value)))
      {
!       if (require_constant_value)
! 	{
! 	  error_init ("initializer element is not constant");
! 	  value = error_mark_node;
! 	}
!       else if (require_constant_elements)
! 	pedwarn ("initializer element is not computable at load time");
      }
  
    /* If this field is empty (and not at the end of structure),
       don't do anything other than checking the initializer.  */
Index: testsuite/gcc.dg/pr17322.c
===================================================================
RCS file: testsuite/gcc.dg/pr17322.c
diff -N testsuite/gcc.dg/pr17322.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/pr17322.c	9 Sep 2004 17:33:44 -0000
***************
*** 0 ****
--- 1,5 ----
+ /* PR 17322 */
+ 
+ struct s { int a; int b[1]; };
+ struct s x;
+ int *y = ((struct s *)&x.a)->b;



More information about the Gcc-patches mailing list