c++ headers w/ -pedantic, overflow in implicit constant conversion

2012-03-14 Thread Stuart Henderson
There are a fair few of these in c++ builds which tend to obscure some
of the actually useful warnings. Antoine noticed it a while ago, Landry
noticed it recently, I see it from time to time..

Any suggestions other than not using -pedantic? (Actually I think
I have seen this without -pedantic too somewhere but I forget where).
Is this just a silly warning or is there actually a problem with the
headers?

This example is from chopping down a file from converters/wv2 (which
is itself a relatively small example) until the warning no longer
occurs then going back one step.

$ cat > a.c
#include 
^D
$ c++ -pedantic -c a.c
In file included from /usr/include/g++/memory:60,
 from /usr/include/g++/string:48,
 from a.c:1:
/usr/include/g++/limits: In static member function 'static char 
std::numeric_limits::min()':
/usr/include/g++/limits:375: warning: overflow in implicit constant conversion
/usr/include/g++/limits: In static member function 'static wchar_t 
std::numeric_limits::max()':
/usr/include/g++/limits:530: warning: overflow in implicit constant conversion



Re: c++ headers w/ -pedantic, overflow in implicit constant conversion

2012-05-10 Thread Landry Breuil
On Thu, Mar 15, 2012 at 11:19:43AM +0100, Marc Espie wrote:
> On Thu, Mar 15, 2012 at 01:39:18AM +, Stuart Henderson wrote:
> > $ c++ -pedantic -c a.c
> > In file included from /usr/include/g++/memory:60,
> >  from /usr/include/g++/string:48,
> >  from a.c:1:
> > /usr/include/g++/limits: In static member function 'static char 
> > std::numeric_limits::min()':
> > /usr/include/g++/limits:375: warning: overflow in implicit constant 
> > conversion
> > /usr/include/g++/limits: In static member function 'static wchar_t 
> > std::numeric_limits::max()':
> > /usr/include/g++/limits:530: warning: overflow in implicit constant 
> > conversion
> 
> It's not even fixed in gcc 4.6.2, not fully anyways.
> 
> The following patch might work, it really needs to be read by people who
> understand this
> 
> - the max warning comes from gcc 4.6.2, this one should be fine.
> - the min warning affects the specialization for char, but char is
> either signed char or unsigned char, so we can borrow the specializations
> from those types.  Preferably directly, to avoid duplication. Obviously,
> gcc will whine at having definitions in the wrong order, so it's possible
> to reorder things to avoid that as well.
> 
> Please test. I've "fixed" limits directly, then backfitted the patch to
> the right src file (been a while since I hacked on this), and I hope it's
> correct.

Can this be reviewed/commited ? Those warnings are really annoying and
hide real errors/warnings.

Landry

> Index: std_limits.h
> ===
> RCS file: /cvs/src/gnu/gcc/libstdc++-v3/include/std/std_limits.h,v
> retrieving revision 1.1.1.1
> diff -u -p -r1.1.1.1 std_limits.h
> --- std_limits.h  15 Oct 2009 17:11:32 -  1.1.1.1
> +++ std_limits.h  15 Mar 2012 10:16:04 -
> @@ -137,7 +137,9 @@
>(__glibcxx_signed (T) ? (T)1 << __glibcxx_digits (T) : (T)0)
>  
>  #define __glibcxx_max(T) \
> -  (__glibcxx_signed (T) ? ((T)1 << __glibcxx_digits (T)) - 1 : ~(T)0)
> +  (__glibcxx_signed (T) ? \
> +  (T)1 << (__glibcxx_digits (T) - 1)) - 1) << 1) + 1) : ~(T)0)
> +
>  
>  #define __glibcxx_digits(T) \
>(sizeof(T) * __CHAR_BIT__ - __glibcxx_signed (T))
> @@ -365,57 +367,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
>static const float_round_style round_style = round_toward_zero;
>  };
>  
> -  /// numeric_limits specialization.
> -  template<>
> -struct numeric_limits
> -{
> -  static const bool is_specialized = true;
> -
> -  static char min() throw()
> -  { return __glibcxx_min(char); }
> -  static char max() throw()
> -  { return __glibcxx_max(char); }
> -
> -  static const int digits = __glibcxx_digits (char);
> -  static const int digits10 = __glibcxx_digits10 (char);
> -  static const bool is_signed = __glibcxx_signed (char);
> -  static const bool is_integer = true;
> -  static const bool is_exact = true;
> -  static const int radix = 2;
> -  static char epsilon() throw()
> -  { return 0; }
> -  static char round_error() throw()
> -  { return 0; }
> -
> -  static const int min_exponent = 0;
> -  static const int min_exponent10 = 0;
> -  static const int max_exponent = 0;
> -  static const int max_exponent10 = 0;
> -
> -  static const bool has_infinity = false;
> -  static const bool has_quiet_NaN = false;
> -  static const bool has_signaling_NaN = false;
> -  static const float_denorm_style has_denorm = denorm_absent;
> -  static const bool has_denorm_loss = false;
> -
> -  static char infinity() throw()
> -  { return char(); }
> -  static char quiet_NaN() throw()
> -  { return char(); }
> -  static char signaling_NaN() throw()
> -  { return char(); }
> -  static char denorm_min() throw()
> -  { return static_cast(0); }
> -
> -  static const bool is_iec559 = false;
> -  static const bool is_bounded = true;
> -  static const bool is_modulo = true;
> -
> -  static const bool traps = __glibcxx_integral_traps;
> -  static const bool tinyness_before = false;
> -  static const float_round_style round_style = round_toward_zero;
> -};
> -
>/// numeric_limits specialization.
>template<>
>  struct numeric_limits
> @@ -508,6 +459,61 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
>{ return static_cast(0); }
>static unsigned char denorm_min() throw()
>{ return static_cast(0); }
> +
> +  static const bool is_iec559 = false;
> +  static const bool is_bounded = true;
> +  static const bool is_modulo = true;
> +
> +  static const bool traps = __glibcxx_integral_traps;
> +  static const bool tinyness_before = false;
> +  static const float_round_style round_style = round_toward_zero;
> +};
> +
> +  /// numeric_limits specialization.
> +  template<>
> +struct numeric_limits
> +{
> +  static const bool is_specialized = true;
> +
> +

Re: c++ headers w/ -pedantic, overflow in implicit constant conversion

2012-05-10 Thread Matthew Dempsky
On Thu, Mar 15, 2012 at 3:19 AM, Marc Espie  wrote:
>  #define __glibcxx_max(T) \
> -  (__glibcxx_signed (T) ? ((T)1 << __glibcxx_digits (T)) - 1 : ~(T)0)
> +  (__glibcxx_signed (T) ? \
> +      (T)1 << (__glibcxx_digits (T) - 1)) - 1) << 1) + 1) : ~(T)0)
> +

How about (T)(((unsigned T)1 << __glibc_digits(T)) - 1)?

Also, we should use (T)-1 << __glibc_digits(T) in __glibc_min to avoid
relying on overflow behavior for signed types.



Re: c++ headers w/ -pedantic, overflow in implicit constant conversion

2012-05-10 Thread Otto Moerbeek
On Thu, May 10, 2012 at 08:46:26AM -0700, Matthew Dempsky wrote:

> On Thu, Mar 15, 2012 at 3:19 AM, Marc Espie  wrote:
> >  #define __glibcxx_max(T) \
> > -  (__glibcxx_signed (T) ? ((T)1 << __glibcxx_digits (T)) - 1 : ~(T)0)
> > +  (__glibcxx_signed (T) ? \
> > +  (T)1 << (__glibcxx_digits (T) - 1)) - 1) << 1) + 1) : ~(T)0)
> > +
> 
> How about (T)(((unsigned T)1 << __glibc_digits(T)) - 1)?
> 
> Also, we should use (T)-1 << __glibc_digits(T) in __glibc_min to avoid
> relying on overflow behavior for signed types.

This could expand to things like "unsigened unsigned int".

-Otto



Re: c++ headers w/ -pedantic, overflow in implicit constant conversion

2012-05-10 Thread Matthew Dempsky
I'm pretty sure unsigned int is never a signed type.


Re: c++ headers w/ -pedantic, overflow in implicit constant conversion

2012-05-10 Thread Matthew Dempsky
Oh even if it's not signed that ternary branch will still be in code. I
see. Hm.
On May 10, 2012 9:23 AM, "Matthew Dempsky"  wrote:


Re: c++ headers w/ -pedantic, overflow in implicit constant conversion

2012-05-10 Thread Marc Espie
On Thu, May 10, 2012 at 08:46:26AM -0700, Matthew Dempsky wrote:
> On Thu, Mar 15, 2012 at 3:19 AM, Marc Espie  wrote:
> >  #define __glibcxx_max(T) \
> > -  (__glibcxx_signed (T) ? ((T)1 << __glibcxx_digits (T)) - 1 : ~(T)0)
> > +  (__glibcxx_signed (T) ? \
> > +  (T)1 << (__glibcxx_digits (T) - 1)) - 1) << 1) + 1) : ~(T)0)
> > +
> 
> How about (T)(((unsigned T)1 << __glibc_digits(T)) - 1)?
> 
> Also, we should use (T)-1 << __glibc_digits(T) in __glibc_min to avoid
> relying on overflow behavior for signed types.

Look, landry just reminded me that I forgot to commit this. It was mostly
awaiting test results, and we've been running with this for almost two
months.

If you think something else is better, take it upstream, since I actually
took the fix from recent gcc, and I'd prefer to avoid diverging too much.



Re: c++ headers w/ -pedantic, overflow in implicit constant conversion

2012-05-10 Thread Miod Vallat
> Look, landry just reminded me that I forgot to commit this. It was mostly
> awaiting test results, and we've been running with this for almost two
> months.
> 
> If you think something else is better, take it upstream, since I actually
> took the fix from recent gcc, and I'd prefer to avoid diverging too much.

May I see your grumpyness licence?



Re: c++ headers w/ -pedantic, overflow in implicit constant conversion

2012-05-10 Thread Otto Moerbeek
On Thu, May 10, 2012 at 05:00:19PM +, Miod Vallat wrote:

> > Look, landry just reminded me that I forgot to commit this. It was mostly
> > awaiting test results, and we've been running with this for almost two
> > months.
> > 
> > If you think something else is better, take it upstream, since I actually
> > took the fix from recent gcc, and I'd prefer to avoid diverging too much.
> 
> May I see your grumpyness licence?

grumpyness is free, right?

-Otto



Re: c++ headers w/ -pedantic, overflow in implicit constant conversion

2012-03-15 Thread Marc Espie
On Thu, Mar 15, 2012 at 01:39:18AM +, Stuart Henderson wrote:
> $ c++ -pedantic -c a.c
> In file included from /usr/include/g++/memory:60,
>  from /usr/include/g++/string:48,
>  from a.c:1:
> /usr/include/g++/limits: In static member function 'static char 
> std::numeric_limits::min()':
> /usr/include/g++/limits:375: warning: overflow in implicit constant conversion
> /usr/include/g++/limits: In static member function 'static wchar_t 
> std::numeric_limits::max()':
> /usr/include/g++/limits:530: warning: overflow in implicit constant conversion

It's not even fixed in gcc 4.6.2, not fully anyways.

The following patch might work, it really needs to be read by people who
understand this

- the max warning comes from gcc 4.6.2, this one should be fine.
- the min warning affects the specialization for char, but char is
either signed char or unsigned char, so we can borrow the specializations
from those types.  Preferably directly, to avoid duplication. Obviously,
gcc will whine at having definitions in the wrong order, so it's possible
to reorder things to avoid that as well.

Please test. I've "fixed" limits directly, then backfitted the patch to
the right src file (been a while since I hacked on this), and I hope it's
correct.


Index: std_limits.h
===
RCS file: /cvs/src/gnu/gcc/libstdc++-v3/include/std/std_limits.h,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 std_limits.h
--- std_limits.h15 Oct 2009 17:11:32 -  1.1.1.1
+++ std_limits.h15 Mar 2012 10:16:04 -
@@ -137,7 +137,9 @@
   (__glibcxx_signed (T) ? (T)1 << __glibcxx_digits (T) : (T)0)
 
 #define __glibcxx_max(T) \
-  (__glibcxx_signed (T) ? ((T)1 << __glibcxx_digits (T)) - 1 : ~(T)0)
+  (__glibcxx_signed (T) ? \
+  (T)1 << (__glibcxx_digits (T) - 1)) - 1) << 1) + 1) : ~(T)0)
+
 
 #define __glibcxx_digits(T) \
   (sizeof(T) * __CHAR_BIT__ - __glibcxx_signed (T))
@@ -365,57 +367,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
   static const float_round_style round_style = round_toward_zero;
 };
 
-  /// numeric_limits specialization.
-  template<>
-struct numeric_limits
-{
-  static const bool is_specialized = true;
-
-  static char min() throw()
-  { return __glibcxx_min(char); }
-  static char max() throw()
-  { return __glibcxx_max(char); }
-
-  static const int digits = __glibcxx_digits (char);
-  static const int digits10 = __glibcxx_digits10 (char);
-  static const bool is_signed = __glibcxx_signed (char);
-  static const bool is_integer = true;
-  static const bool is_exact = true;
-  static const int radix = 2;
-  static char epsilon() throw()
-  { return 0; }
-  static char round_error() throw()
-  { return 0; }
-
-  static const int min_exponent = 0;
-  static const int min_exponent10 = 0;
-  static const int max_exponent = 0;
-  static const int max_exponent10 = 0;
-
-  static const bool has_infinity = false;
-  static const bool has_quiet_NaN = false;
-  static const bool has_signaling_NaN = false;
-  static const float_denorm_style has_denorm = denorm_absent;
-  static const bool has_denorm_loss = false;
-
-  static char infinity() throw()
-  { return char(); }
-  static char quiet_NaN() throw()
-  { return char(); }
-  static char signaling_NaN() throw()
-  { return char(); }
-  static char denorm_min() throw()
-  { return static_cast(0); }
-
-  static const bool is_iec559 = false;
-  static const bool is_bounded = true;
-  static const bool is_modulo = true;
-
-  static const bool traps = __glibcxx_integral_traps;
-  static const bool tinyness_before = false;
-  static const float_round_style round_style = round_toward_zero;
-};
-
   /// numeric_limits specialization.
   template<>
 struct numeric_limits
@@ -508,6 +459,61 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
   { return static_cast(0); }
   static unsigned char denorm_min() throw()
   { return static_cast(0); }
+
+  static const bool is_iec559 = false;
+  static const bool is_bounded = true;
+  static const bool is_modulo = true;
+
+  static const bool traps = __glibcxx_integral_traps;
+  static const bool tinyness_before = false;
+  static const float_round_style round_style = round_toward_zero;
+};
+
+  /// numeric_limits specialization.
+  template<>
+struct numeric_limits
+{
+  static const bool is_specialized = true;
+
+  static char min() throw()
+  { return __glibcxx_signed(char) ? 
+   numeric_limits::min() :
+   numeric_limits::min(); }
+  static char max() throw()
+  { return __glibcxx_signed(char) ? 
+   numeric_limits::max() :
+   numeric_limits::max(); }
+
+  static const int digits = __glibcxx_digits (char);
+  static const int digits10 = __glibcxx_digits10 (char);
+  

Re: c++ headers w/ -pedantic, overflow in implicit constant conversion

2012-03-15 Thread Remco
Stuart Henderson wrote:

> There are a fair few of these in c++ builds which tend to obscure some
> of the actually useful warnings. Antoine noticed it a while ago, Landry
> noticed it recently, I see it from time to time..
> 
> Any suggestions other than not using -pedantic? (Actually I think
> I have seen this without -pedantic too somewhere but I forget where).
> Is this just a silly warning or is there actually a problem with the
> headers?
> 
> This example is from chopping down a file from converters/wv2 (which
> is itself a relatively small example) until the warning no longer
> occurs then going back one step.
> 
> $ cat > a.c
> #include 
> ^D
> $ c++ -pedantic -c a.c
> In file included from /usr/include/g++/memory:60,
>  from /usr/include/g++/string:48,
>  from a.c:1:
> /usr/include/g++/limits: In static member function 'static char
> std::numeric_limits::min()': /usr/include/g++/limits:375: warning:
> overflow in implicit constant conversion /usr/include/g++/limits: In
> static member function 'static wchar_t
> std::numeric_limits::max()': /usr/include/g++/limits:530:
> warning: overflow in implicit constant conversion


Not a solution, but hopefully helpful.

If I interpreted everything correctly, the macro __glibcxx_min
in /usr/include/g++/limits is used in std::numeric_limits::min().

It uses something like ((char)1<<7) to determine the minimum value of a
char. I suspect that ((char)1<<7), or (1<<7) before being converted to
char, is interpreted as 128 in an intermediate stage of the processing.
When being pedantic 128 wouldn't fit in a char at that moment.
(AFAICT -128 <= char <= 127)

I suspect something similar is the case for the max function. 128 is used as
an intermediate result. Subtracting 1 gets the proper end result. But the
intermediate result (128) doesn't fit in a char when having a pedantic look
at this.


Attached is the simplest case I could come up with to reproduce this:

btw, this is on:
OpenBSD 5.0 (GENERIC.MP) #63: Wed Aug 17 10:14:30 MDT 2011
dera...@amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP

make a file, e.g. t.cc, containing:
char
test1()
{
return ((char)1<<6);
}


char
test2()
{
return ((char)1<<7);
}


char
test3()
{
return ((char)1<<8);
}


compile using C++ compiler:

being pedantic:
$ c++ -pedantic -c t.cc
t.cc: In function 'char test2()':
t.cc:11: warning: overflow in implicit constant conversion
t.cc: In function 'char test3()':
t.cc:18: warning: overflow in implicit constant conversion

NOT being pedantic:
$ c++ -c t.cc
t.cc: In function 'char test3()':
t.cc:18: warning: overflow in implicit constant conversion


copy to a .c file:
$ cp t.cc t.c

compile using C compiler:

being pedantic:
$ cc -pedantic -c t.c
t.c: In function 'test2':
t.c:11: warning: overflow in implicit constant conversion
t.c: In function 'test3':
t.c:18: warning: overflow in implicit constant conversion

NOT being pedantic:
$ cc -c t.c
t.c: In function 'test3':
t.c:18: warning: overflow in implicit constant conversion