🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gcc.bug
Article #77

not all constant expressions are checked for overflow (GCC 2.3.1)

#77
From: Paul Eggert
Date: Wed, 04 Nov 1992 19:14
182 lines
6637 bytes
GCC 2.3.1 checks some constant expressions for integer overflow, but it misses
constant expressions that are array bounds, bitfield sizes, array index
labels, or arguments to __builtin_args_info.  For example, GCC 2.3.1 misses
the overflows in each line of the following program:

	char a[2147483647 + 2147483647 + 3];
	struct { int x : 2147483647 + 2147483647 + 3; } b;
	int c[10] = { [2147483647 + 2147483647 + 3 ... 9] 0 };
	int d[10] = { [2147483647 + 2147483647 + 3] 0 };
	int e() { return __builtin_args_info (1 << 31 << 31 << 2); }

Here is a patch.

Wed Nov  4 19:04:56 1992  Paul Eggert  (eggert@twinsun.com)

	c-decl.c (finish_decl,grokdeclarator,finish_struct,build_enumerator):
	Check all constant expressions, not just initializers.
	c-typeck.c (process_init_constructor): Likewise.
	expr.c (expand_builtin): Likewise.

===================================================================
RCS file: c-decl.c,v
retrieving revision 2.3
retrieving revision 2.3.1.1
diff -c -r2.3 -r2.3.1.1
*** c-decl.c	1992/10/28 21:28:28	2.3
--- c-decl.c	1992/11/04 19:04:56	2.3.1.1
***************
*** 3276,3284 ****
  	}
  
        if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
! 	  && DECL_SIZE (decl) != 0
! 	  && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
! 	error_with_decl (decl, "storage size of `%s' isn't constant");
      }
  
    /* Output the assembler code and/or RTL code for variables and functions,
--- 3276,3286 ----
  	}
  
        if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
! 	  && DECL_SIZE (decl) != 0)
! 	if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST)
! 	  constant_expression_warning (DECL_SIZE (decl));
! 	else
! 	  error_with_decl (decl, "storage size of `%s' isn't constant");
      }
  
    /* Output the assembler code and/or RTL code for variables and functions,
***************
*** 3924,3929 ****
--- 3926,3932 ----
  		pedwarn ("ANSI C forbids zero-size array `%s'", name);
  	      if (TREE_CODE (size) == INTEGER_CST)
  		{
+ 		  constant_expression_warning (size);
  		  if (INT_CST_LT (size, integer_zero_node))
  		    {
  		      error ("size of array `%s' is negative", name);
***************
*** 4874,4884 ****
        /* Detect invalid bit-field size.  */
        if (DECL_INITIAL (x))
  	STRIP_NOPS (DECL_INITIAL (x));
!       if (DECL_INITIAL (x) && TREE_CODE (DECL_INITIAL (x)) != INTEGER_CST)
! 	{
! 	  error_with_decl (x, "bit-field `%s' width not an integer constant");
! 	  DECL_INITIAL (x) = NULL;
! 	}
  
        /* Detect invalid bit-field type.  */
        if (DECL_INITIAL (x)
--- 4877,4890 ----
        /* Detect invalid bit-field size.  */
        if (DECL_INITIAL (x))
  	STRIP_NOPS (DECL_INITIAL (x));
!       if (DECL_INITIAL (x))
! 	if (TREE_CODE (DECL_INITIAL (x)) == INTEGER_CST)
! 	  constant_expression_warning (DECL_INITIAL (x));
! 	else
! 	  {
! 	    error_with_decl (x, "bit-field `%s' width not an integer constant");
! 	    DECL_INITIAL (x) = NULL;
! 	  }
  
        /* Detect invalid bit-field type.  */
        if (DECL_INITIAL (x)
***************
*** 5286,5297 ****
    if (value)
      STRIP_TYPE_NOPS (value);
  
!   if (value != 0 && TREE_CODE (value) != INTEGER_CST)
!     {
!       error ("enumerator value for `%s' not integer constant",
! 	     IDENTIFIER_POINTER (name));
!       value = 0;
!     }
  
    /* Default based on previous value.  */
    /* It should no longer be possible to have NON_LVALUE_EXPR
--- 5292,5306 ----
    if (value)
      STRIP_TYPE_NOPS (value);
  
!   if (value != 0)
!     if (TREE_CODE (value) == INTEGER_CST)
!       constant_expression_warning (value);
!     else
!       {
! 	error ("enumerator value for `%s' not integer constant",
! 	       IDENTIFIER_POINTER (name));
! 	value = 0;
!       }
  
    /* Default based on previous value.  */
    /* It should no longer be possible to have NON_LVALUE_EXPR
===================================================================
RCS file: c-typeck.c,v
retrieving revision 2.3
retrieving revision 2.3.1.1
diff -c -r2.3 -r2.3.1.1
*** c-typeck.c	1992/10/27 00:02:20	2.3
--- c-typeck.c	1992/11/04 19:04:56	2.3.1.1
***************
*** 4985,4990 ****
--- 4985,4993 ----
  		  if (start_index && TREE_CODE (start_index) == NON_LVALUE_EXPR)
  		    start_index = TREE_OPERAND (start_index, 0);
  
+ 		  constant_expression_warning (start_index);
+ 		  constant_expression_warning (end_index);
+ 
  		  if ((TREE_CODE (start_index) == IDENTIFIER_NODE) 
  		      || (TREE_CODE (end_index) == IDENTIFIER_NODE))
  		    error ("field name used as index in array initializer");
***************
*** 5023,5029 ****
  		       || (max_index && tree_int_cst_lt (max_index, index)))
  		error ("array index out of range in initializer");
  	      else
! 		current_index = index, win = 1;
  
  	      if (!win)
  		TREE_VALUE (tail) = error_mark_node;
--- 5026,5035 ----
  		       || (max_index && tree_int_cst_lt (max_index, index)))
  		error ("array index out of range in initializer");
  	      else
! 		{
! 		  constant_expression_warning (index);
! 		  current_index = index, win = 1;
! 		}
  
  	      if (!win)
  		TREE_VALUE (tail) = error_mark_node;
===================================================================
RCS file: expr.c,v
retrieving revision 2.3
retrieving revision 2.3.1.1
diff -c -r2.3 -r2.3.1.1
*** expr.c	1992/10/25 19:47:00	2.3
--- expr.c	1992/11/04 19:04:56	2.3.1.1
***************
*** 5616,5622 ****
  	      {
  		int wordnum = TREE_INT_CST_LOW (arg);
  
! 		if (wordnum < 0 || wordnum >= nwords)
  		  error ("argument of __builtin_args_info out of range");
  		else
  		  return GEN_INT (word_ptr[wordnum]);
--- 5616,5623 ----
  	      {
  		int wordnum = TREE_INT_CST_LOW (arg);
  
! 		constant_expression_warning (arg);
! 		if (wordnum < 0 || wordnum >= nwords || TREE_INT_CST_HIGH (arg))
  		  error ("argument of __builtin_args_info out of range");
  		else
  		  return GEN_INT (word_ptr[wordnum]);
Technical Details
Message-ID: <9211041914.AA13048@farside.twinsun.com>
Path: arc1-ca.pugleaf.net!sparky!uunet!charon.amdahl.com!pacbell.com!iggy.GW.Vitalink.COM!cs.widener.edu!umn.edu!spool.mu.edu!yale.edu!qt.cs.utexas.edu!cs.utexas.edu!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!twinsun.COM!eggert

Show Full Headers
Complete Article Headers
Newsgroups: gnu.gcc.bug
Path: arc1-ca.pugleaf.net!sparky!uunet!charon.amdahl.com!pacbell.com!iggy.GW.Vitalink.COM!cs.widener.edu!umn.edu!spool.mu.edu!yale.edu!qt.cs.utexas.edu!cs.utexas.edu!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!twinsun.COM!eggert
From: eggert@twinsun.COM (Paul Eggert)
Subject: not all constant expressions are checked for overflow (GCC 2.3.1)
Message-ID: <9211041914.AA13048@farside.twinsun.com>
Sender: gnulists@ai.mit.edu
Organization: GNUs Not Usenet
Distribution: gnu
Date: Wed, 4 Nov 1992 19:14:06 GMT
Approved: bug-gcc@prep.ai.mit.edu
Lines: 183