[PATCH] Document and correct ABS_EXPR usage

Roger Sayle roger@eyesopen.com
Mon Jun 2 13:11:00 GMT 2003


During my recent development of the patch to support C99's cabs, cabsf
and cabsl functions as GCC builtins, I was misled by the various bits
of code in the compiler that assume ABS_EXPR may be used to implement
complex abs.  So I simply added BUILT_IN_CABS to the appropriate switch
case in c-common.c's expand_tree_builtin and was rewarded with ICEs.

Of course ABS_EXPR with a complex TREE_TYPE can't be used to represent
complex abs.  The result of a complex abs operation isn't a complex
type but a scalar type, and you wouldn't believe how much of GCC's
middle-end assumes that the TREE_TYPE of an expression actually is
the result type of that expression :>

I then looked for the documentation of ABS_EXPR in the GCC internal
manuals, and of course it isn't documented, however the comments in
tree.def explicitly state that its is only used for integer and real
values.  Checking "cvs annotate expr.c" it appears that this
misunderstanding predates the current repository.

The following patch documents the correct usage of ABS_EXPR in
c-tree.texi and removes code from the rest of the compiler that
supports/permits its incorrect use with complex types.  The text
recommends the use of BUILT_IN_CABS for representing complex abs
in trees, as introduced in my preceding patch, and therefore this
patch is (partially) dependent on that one.


The following patch has been tested on i686-pc-linux-gnu with a
complete bootstrap, all languages except treelang, and regression
tested with a top-level "make -k check" with no new failures.

Ok for mainline?


2003-06-02  Roger Sayle  <roger@eyesopen.com>

	* expr.c (expand_expr): If an ABS_EXPR has a complex type, abort.
	* c-typeck.c (build_unary_op): COMPLEX_TYPE is not a valid
	typecode for an ABS_EXPR.

	* doc/c-tree.texi: Document ABS_EXPR.


Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.544
diff -c -3 -p -r1.544 expr.c
*** expr.c	30 May 2003 17:49:44 -0000	1.544
--- expr.c	1 Jun 2003 20:31:40 -0000
*************** expand_expr (exp, target, tmode, modifie
*** 8435,8444 ****
        if (modifier == EXPAND_STACK_PARM)
  	target = 0;

!       /* Handle complex values specially.  */
        if (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
  	  || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
! 	return expand_complex_abs (mode, op0, target, unsignedp);

        /* Unsigned abs is simply the operand.  Testing here means we don't
  	 risk generating incorrect code below.  */
--- 8435,8444 ----
        if (modifier == EXPAND_STACK_PARM)
  	target = 0;

!       /* ABS_EXPR is not valid for complex arguments.  */
        if (GET_MODE_CLASS (mode) == MODE_COMPLEX_INT
  	  || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT)
! 	abort ();

        /* Unsigned abs is simply the operand.  Testing here means we don't
  	 risk generating incorrect code below.  */
Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.238
diff -c -3 -p -r1.238 c-typeck.c
*** c-typeck.c	5 May 2003 20:31:42 -0000	1.238
--- c-typeck.c	1 Jun 2003 20:31:42 -0000
*************** build_unary_op (code, xarg, flag)
*** 2794,2801 ****
        break;

      case ABS_EXPR:
!       if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
! 	    || typecode == COMPLEX_TYPE))
  	{
  	  error ("wrong type argument to abs");
  	  return error_mark_node;
--- 2794,2800 ----
        break;

      case ABS_EXPR:
!       if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE))
  	{
  	  error ("wrong type argument to abs");
  	  return error_mark_node;
Index: doc/c-tree.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/c-tree.texi,v
retrieving revision 1.42
diff -c -3 -p -r1.42 c-tree.texi
*** doc/c-tree.texi	31 May 2003 13:23:30 -0000	1.42
--- doc/c-tree.texi	1 Jun 2003 20:31:43 -0000
*************** This macro returns the attributes on the
*** 1722,1727 ****
--- 1722,1728 ----
  @findex PTRMEM_CST_MEMBER
  @tindex VAR_DECL
  @tindex NEGATE_EXPR
+ @tindex ABS_EXPR
  @tindex BIT_NOT_EXPR
  @tindex TRUTH_NOT_EXPR
  @tindex ADDR_EXPR
*************** determined by looking at the type of the
*** 1916,1921 ****
--- 1917,1936 ----

  The behavior of this operation on signed arithmetic overflow is
  controlled by the @code{flag_wrapv} and @code{flag_trapv} variables.
+
+ @item ABS_EXPR
+ These nodes represent the absolute value of the single operand, for
+ both integer and floating-point types.  This is typically used to
+ implement the @code{abs}, @code{labs} and @code{llabs} builtins for
+ integer types, and the @code{fabs}, @code{fabsf} and @code{fabsl}
+ builtins for floating point types.  The type of abs operation can
+ be determined by looking at the type of the expression.
+
+ This node is not used for complex types.  To represent the modulus
+ or complex abs of a complex value, use the @code{BUILT_IN_CABS},
+ @code{BUILT_IN_CABSF} or @code{BUILT_IN_CABSL} builtins, as used
+ to implement the C99 @code{cabs}, @code{cabsf} and @code{cabsl}
+ built-in functions.

  @item BIT_NOT_EXPR
  These nodes represent bitwise complement, and will always have integral

Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833



More information about the Gcc-patches mailing list