This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH: Deprecate min/max


This patch deprecates the minimum and maximum operators in the C++
front end.  I'll remove them on the mainline after 4.0 is out.

Tested on x86_64-unknown-linux-gnu, applied on the 4.0 branch and the
mainline.  WWW patch to follow.

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com

2005-03-22  Mark Mitchell  <mark@codesourcery.com>

	* doc/extend.texi: Deprecate C++ min/max operators.

2005-03-22  Mark Mitchell  <mark@codesourcery.com>

	* parser.c (cp_parser_warn_min_max): New function.
	(cp_parser_binary_expression): Use it.
	(cp_parser_assignment_operator_opt): Likewise.
	(cp_parser_operator): Likewise.

2005-03-22  Mark Mitchell  <mark@codesourcery.com>

	* g++.dg/opt/max1.C: Run with -Wno-deprecated.
	* g++.dg/opt/pr7503-2.C: Likewise.
	* g++.dg/opt/pr7503-3.C: Likewise.
	* g++.dg/opt/pr7503-4.C: Likewise.
	* g++.dg/opt/pr7503-5.C: Likewise.
	* g++.dg/warn/minmax.C: New test.

Index: doc/extend.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/extend.texi,v
retrieving revision 1.240.2.4
diff -c -5 -p -r1.240.2.4 extend.texi
*** doc/extend.texi	19 Mar 2005 20:59:37 -0000	1.240.2.4
--- doc/extend.texi	22 Mar 2005 22:58:39 -0000
*************** test for the GNU compiler the same way a
*** 9117,9127 ****
  predefined macro @code{__GNUC__}.  You can also use @code{__GNUG__} to
  test specifically for GNU C++ (@pxref{Common Predefined Macros,,
  Predefined Macros,cpp,The GNU C Preprocessor}).
  
  @menu
- * Min and Max::		C++ Minimum and maximum operators.
  * Volatiles::		What constitutes an access to a volatile object.
  * Restricted Pointers:: C99 restricted pointers and references.
  * Vague Linkage::       Where G++ puts inlines, vtables and such.
  * C++ Interface::       You can use a single C++ header file for both
                          declarations and definitions.
--- 9117,9126 ----
*************** Predefined Macros,cpp,The GNU C Preproce
*** 9134,9188 ****
  * Java Exceptions::     Tweaking exception handling to work with Java.
  * Deprecated Features:: Things will disappear from g++.
  * Backwards Compatibility:: Compatibilities with earlier definitions of C++.
  @end menu
  
- @node Min and Max
- @section Minimum and Maximum Operators in C++
- 
- It is very convenient to have operators which return the ``minimum'' or the
- ``maximum'' of two arguments.  In GNU C++ (but not in GNU C),
- 
- @table @code
- @item @var{a} <? @var{b}
- @findex <?
- @cindex minimum operator
- is the @dfn{minimum}, returning the smaller of the numeric values
- @var{a} and @var{b};
- 
- @item @var{a} >? @var{b}
- @findex >?
- @cindex maximum operator
- is the @dfn{maximum}, returning the larger of the numeric values @var{a}
- and @var{b}.
- @end table
- 
- These operations are not primitive in ordinary C++, since you can
- use a macro to return the minimum of two things in C++, as in the
- following example.
- 
- @smallexample
- #define MIN(X,Y) ((X) < (Y) ? : (X) : (Y))
- @end smallexample
- 
- @noindent
- You might then use @w{@samp{int min = MIN (i, j);}} to set @var{min} to
- the minimum value of variables @var{i} and @var{j}.
- 
- However, side effects in @code{X} or @code{Y} may cause unintended
- behavior.  For example, @code{MIN (i++, j++)} will fail, incrementing
- the smaller counter twice.  The GNU C @code{typeof} extension allows you
- to write safe macros that avoid this kind of problem (@pxref{Typeof}).
- However, writing @code{MIN} and @code{MAX} as macros also forces you to
- use function-call notation for a fundamental arithmetic operation.
- Using GNU C++ extensions, you can write @w{@samp{int min = i <? j;}}
- instead.
- 
- Since @code{<?} and @code{>?} are built into the compiler, they properly
- handle expressions with side-effects;  @w{@samp{int min = i++ <? j++;}}
- works correctly.
- 
  @node Volatiles
  @section When is a Volatile Object Accessed?
  @cindex accessing volatiles
  @cindex volatile read
  @cindex volatile write
--- 9133,9142 ----
*************** it is required for backwards compatibili
*** 9825,9834 ****
--- 9779,9793 ----
  G++ allows a virtual function returning @samp{void *} to be overridden
  by one returning a different pointer type.  This extension to the
  covariant return type rules is now deprecated and will be removed from a
  future version.
  
+ The G++ minimum and maximum operators (@samp{<?} and @samp{>?}) and
+ their compound forms (@samp{<?=}) and @samp{>?=}) have been deprecated
+ and will be removed in a future version.  Code using these operators
+ should be modified to use @code{std::min} and @code{std::max} instead.
+ 
  The named return value extension has been deprecated, and is now
  removed from G++.
  
  The use of initializer lists with new expressions has been deprecated,
  and is now removed from G++.
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.319.2.3
diff -c -5 -p -r1.319.2.3 parser.c
*** cp/parser.c	22 Mar 2005 14:50:05 -0000	1.319.2.3
--- cp/parser.c	22 Mar 2005 22:52:14 -0000
*************** static bool
*** 1785,1794 ****
--- 1785,1804 ----
  cp_parser_is_keyword (cp_token* token, enum rid keyword)
  {
    return token->keyword == keyword;
  }
  
+ /* A minimum or maximum operator has been seen.  As these are
+    deprecated, issue a warning.  */
+ 
+ static inline void
+ cp_parser_warn_min_max (void)
+ {
+   if (warn_deprecated && !in_system_header)
+     warning ("minimum/maximum operators are deprecated");
+ }
+ 
  /* If not parsing tentatively, issue a diagnostic of the form
        FILE:LINE: MESSAGE before TOKEN
     where TOKEN is the next token in the input stream.  MESSAGE
     (specified by the caller) is usually of the form "expected
     OTHER-TOKEN".  */
*************** cp_parser_binary_expression (cp_parser* 
*** 5399,5408 ****
--- 5409,5421 ----
  
    for (;;)
      {
        /* Get an operator token.  */
        token = cp_lexer_peek_token (parser->lexer);
+       if (token->type == CPP_MIN || token->type == CPP_MAX)
+ 	cp_parser_warn_min_max ();
+ 
        new_prec = TOKEN_PRECEDENCE (token);
  
        /* Popping an entry off the stack means we completed a subexpression:
           - either we found a token which is not an operator (`>' where it is not
             an operator, or prec == PREC_NOT_OPERATOR), in which case popping
*************** cp_parser_assignment_operator_opt (cp_pa
*** 5654,5667 ****
--- 5667,5682 ----
        op = BIT_IOR_EXPR;
        break;
  
      case CPP_MIN_EQ:
        op = MIN_EXPR;
+       cp_parser_warn_min_max ();
        break;
  
      case CPP_MAX_EQ:
        op = MAX_EXPR;
+       cp_parser_warn_min_max ();
        break;
  
      default:
        /* Nothing else is an assignment operator.  */
        op = ERROR_MARK;
*************** cp_parser_operator (cp_parser* parser)
*** 8037,8058 ****
--- 8052,8077 ----
        return ansi_opname (ARRAY_REF);
  
        /* Extensions.  */
      case CPP_MIN:
        id = ansi_opname (MIN_EXPR);
+       cp_parser_warn_min_max ();
        break;
  
      case CPP_MAX:
        id = ansi_opname (MAX_EXPR);
+       cp_parser_warn_min_max ();
        break;
  
      case CPP_MIN_EQ:
        id = ansi_assopname (MIN_EXPR);
+       cp_parser_warn_min_max ();
        break;
  
      case CPP_MAX_EQ:
        id = ansi_assopname (MAX_EXPR);
+       cp_parser_warn_min_max ();
        break;
  
      default:
        /* Anything else is an error.  */
        break;
Index: testsuite/g++.dg/opt/max1.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/opt/max1.C,v
retrieving revision 1.3
diff -c -5 -p -r1.3 max1.C
*** testsuite/g++.dg/opt/max1.C	20 Dec 2004 21:07:13 -0000	1.3
--- testsuite/g++.dg/opt/max1.C	22 Mar 2005 22:52:15 -0000
***************
*** 1,9 ****
  /* PR middle-end/19068 */
  /* Test case by Andrew Pinski <pinskia@physics.uc.edu> */
  /* { dg-do run } */
! /* { dg-options "-O2" } */
  
  extern "C" void abort (void);
  
  long fff[10];
  
--- 1,9 ----
  /* PR middle-end/19068 */
  /* Test case by Andrew Pinski <pinskia@physics.uc.edu> */
  /* { dg-do run } */
! /* { dg-options "-O2 -Wno-deprecated" } */
  
  extern "C" void abort (void);
  
  long fff[10];
  
Index: testsuite/g++.dg/opt/pr7503-2.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/opt/pr7503-2.C,v
retrieving revision 1.1
diff -c -5 -p -r1.1 pr7503-2.C
*** testsuite/g++.dg/opt/pr7503-2.C	21 Sep 2004 16:20:12 -0000	1.1
--- testsuite/g++.dg/opt/pr7503-2.C	22 Mar 2005 22:52:15 -0000
***************
*** 1,8 ****
  // PR c++/7503
  // { dg-do run }
! // { dg-options "-O2" }
  
  extern "C" void abort();
  
  void test1a()
  {
--- 1,8 ----
  // PR c++/7503
  // { dg-do run }
! // { dg-options "-O2 -Wno-deprecated" }
  
  extern "C" void abort();
  
  void test1a()
  {
Index: testsuite/g++.dg/opt/pr7503-3.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/opt/pr7503-3.C,v
retrieving revision 1.2
diff -c -5 -p -r1.2 pr7503-3.C
*** testsuite/g++.dg/opt/pr7503-3.C	25 Nov 2004 17:11:33 -0000	1.2
--- testsuite/g++.dg/opt/pr7503-3.C	22 Mar 2005 22:52:15 -0000
***************
*** 1,8 ****
  // PR c++/7503
  // { dg-do compile }
! // { dg-options "-O2" }
  
  extern int A, B;
  
  void test1()
  {
--- 1,8 ----
  // PR c++/7503
  // { dg-do compile }
! // { dg-options "-O2 -Wno-deprecated" }
  
  extern int A, B;
  
  void test1()
  {
Index: testsuite/g++.dg/opt/pr7503-4.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/opt/pr7503-4.C,v
retrieving revision 1.1
diff -c -5 -p -r1.1 pr7503-4.C
*** testsuite/g++.dg/opt/pr7503-4.C	21 Sep 2004 16:20:12 -0000	1.1
--- testsuite/g++.dg/opt/pr7503-4.C	22 Mar 2005 22:52:15 -0000
***************
*** 1,8 ****
  // PR c++/7503
  // { dg-do run }
! // { dg-options "-O2" }
  
  extern "C" void abort();
  
  void test1a()
  {
--- 1,8 ----
  // PR c++/7503
  // { dg-do run }
! // { dg-options "-O2 -Wno-deprecated" }
  
  extern "C" void abort();
  
  void test1a()
  {
Index: testsuite/g++.dg/opt/pr7503-5.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/opt/pr7503-5.C,v
retrieving revision 1.1
diff -c -5 -p -r1.1 pr7503-5.C
*** testsuite/g++.dg/opt/pr7503-5.C	21 Sep 2004 16:20:12 -0000	1.1
--- testsuite/g++.dg/opt/pr7503-5.C	22 Mar 2005 22:52:15 -0000
***************
*** 1,8 ****
  // PR c++/7503
  // { dg-do run }
! // { dg-options "-O2" }
  
  extern "C" void abort();
  
  void test1a()
  {
--- 1,8 ----
  // PR c++/7503
  // { dg-do run }
! // { dg-options "-O2 -Wno-deprecated" }
  
  extern "C" void abort();
  
  void test1a()
  {
Index: testsuite/g++.dg/warn/minmax.C
===================================================================
RCS file: testsuite/g++.dg/warn/minmax.C
diff -N testsuite/g++.dg/warn/minmax.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/warn/minmax.C	22 Mar 2005 22:52:15 -0000
***************
*** 0 ****
--- 1,15 ----
+ int i, j, k;
+ 
+ void f() {
+   i = j <? k; // { dg-warning "deprecated" }
+   i = j >? k; // { dg-warning "deprecated" }
+   i <?= j; // { dg-warning "deprecated" }
+   i >?= j; // { dg-warning "deprecated" }
+ }
+ 
+ struct S {
+   void operator<?(int); // { dg-warning "deprecated" }
+   void operator>?(int); // { dg-warning "deprecated" }
+   void operator<?=(int); // { dg-warning "deprecated" }
+   void operator>?=(int); // { dg-warning "deprecated" }
+ };


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]