[Bug c/90081] stdint constant macros evaluating to wrong type

2019-04-18 Thread harald at gigawatt dot nl
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90081

--- Comment #10 from Harald van Dijk  ---
(In reply to jos...@codesourcery.com from comment #9)

Thanks, appreciate the explanation. I guess I'm less willing to trust that the
interpretation that makes sense is the one that's intended, but I can see that
either you're right or the requirements are unclear, and either of those leads
to the same conclusion here.

[Bug c/90081] stdint constant macros evaluating to wrong type

2019-04-18 Thread joseph at codesourcery dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90081

--- Comment #9 from joseph at codesourcery dot com  ---
On Thu, 18 Apr 2019, harald at gigawatt dot nl wrote:

> > I think expanding the macro to its argument is clearly correct here, 
> > including for UINT8_C, as the interpretation suggested in DR#456 
> > regarding having an unsigned type in #if leads to the obvious absurdities 
> > I described in reflector message 13320 (15 May 2014).
> 
> That pre-dates the DR's proposed committee response, which is from Oct 2014.

I don't think the committee response paid any attention to the points I 
raised; I think a supposition that compiler magic would be needed is 
inaccurate as the proper reading of the changes in the C99 TCs is that 
they specifically avoid needing such magic.  In any case, it says nothing 
about the types of these macros in #if.  I agree with the conclusion that 
there is no defect (as I think the common-sense reading of the standard 
text is that the promoted type is the result of promoting outside #if, 
just like the limits are the limits of the type outside #if - the limits 
being otherwise would contradict express normative text about the values 
of certain macros).

[Bug c/90081] stdint constant macros evaluating to wrong type

2019-04-18 Thread harald at gigawatt dot nl
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90081

--- Comment #8 from Harald van Dijk  ---
(In reply to jos...@codesourcery.com from comment #7)
> No, INT8_C(5) must expand to have type int, not int_least8_t, if 
> int_least8_t promotes to int.  See 7.20.4#3, "The type of the expression 
> shall have the same type as would an expression of the corresponding type 
> converted according to the integer promotions.".  *Not* the type itself, 
> the promoted type.

Good point, my earlier suggested definition is missing an extra + to handle
that.

> I think expanding the macro to its argument is clearly correct here, 
> including for UINT8_C, as the interpretation suggested in DR#456 
> regarding having an unsigned type in #if leads to the obvious absurdities 
> I described in reflector message 13320 (15 May 2014).

That pre-dates the DR's proposed committee response, which is from Oct 2014.

Are absurdities not just the natural result of requiring all preprocessor
number processing to be done in (u)intmax_t? We already have the situation that
e.g. 0U > -1LL is required (under obvious assumptions about type widths) to
give different results in #if expressions than outside of them, and GCC
implements that.

[Bug c/90081] stdint constant macros evaluating to wrong type

2019-04-18 Thread joseph at codesourcery dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90081

--- Comment #7 from joseph at codesourcery dot com  ---
On Sat, 13 Apr 2019, bafap5 at yahoo dot com wrote:

>   int x = sizeof ((int8_t) 5); /* Correct, gives 1 */
>   int y = sizeof (INT8_C(5));  /* Incorrect, gives 4 */

No, INT8_C(5) must expand to have type int, not int_least8_t, if 
int_least8_t promotes to int.  See 7.20.4#3, "The type of the expression 
shall have the same type as would an expression of the corresponding type 
converted according to the integer promotions.".  *Not* the type itself, 
the promoted type.

I think expanding the macro to its argument is clearly correct here, 
including for UINT8_C, as the interpretation suggested in DR#456 
regarding having an unsigned type in #if leads to the obvious absurdities 
I described in reflector message 13320 (15 May 2014).

[Bug c/90081] stdint constant macros evaluating to wrong type

2019-04-16 Thread harald at gigawatt dot nl
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90081

--- Comment #6 from Harald van Dijk  ---
(In reply to Guy Perfect from comment #5)
> (In reply to Harald van Dijk from comment #4)
> That was my line of thinking: supplying a cast in the macro.

Keep in mind that inside #if expressions, there cannot be and will not be any
cast. That's the reason I included the + there.

> Even in the
> case of negative values being cast to unsigned types, the language spec
> provides a rule for that, so the behavior is defined independent of the
> implementation:

As Andreas Schwab pointed out, the behaviour of UINT8_C in that case is
undefined, even if the behaviour of a cast would be defined. It simply does not
matter what happens in that case.

> I think the ticket was marked "resolved invalid" prematurely, as there's
> clearly a meaningful problem and a meaningful solution.

I do think it's rightly closed, but for a reason not yet mentioned: these
macros are not defined by GCC's . If this required compiler magic to
implement, it would be primarily a GCC bug, but the fact that no compiler magic
is needed means this is purely a glibc bug, so should be filed there.

[Bug c/90081] stdint constant macros evaluating to wrong type

2019-04-15 Thread bafap5 at yahoo dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90081

--- Comment #5 from Guy Perfect  ---
(In reply to Harald van Dijk from comment #4)
That was my line of thinking: supplying a cast in the macro. Even in the case
of negative values being cast to unsigned types, the language spec provides a
rule for that, so the behavior is defined independent of the implementation:

"[... T]he value is converted to unsigned by adding to it one greater than the
largest number that can be represented in the unsigned integer type."

and

"In a two's-complement representation, there is no actual change in the bit
pattern except filling the high-order bits with copies of the sign bit if the
unsigned integer has greater size."

I think the ticket was marked "resolved invalid" prematurely, as there's
clearly a meaningful problem and a meaningful solution.

[Bug c/90081] stdint constant macros evaluating to wrong type

2019-04-15 Thread harald at gigawatt dot nl
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90081

Harald van Dijk  changed:

   What|Removed |Added

 CC||harald at gigawatt dot nl

--- Comment #4 from Harald van Dijk  ---
(In reply to Martin Sebor from comment #3)
> UINT8_C(-5) isn't valid but expanding the macros to their arguments isn't
> conforming either.  C11 DR #456 suggests compiler magic is necessary to make
> the macros correct:
> http://www.open-std.org/jtc1/sc22/wg14/www/docs/summary.htm#dr_456 (Also see
> C99 DR 209: http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_209.htm).

It doesn't seem like compiler magic is really needed:

#define UINT8_C(x) ((__uint8_t) +(x##U))

This works correctly even in #if expressions because of the replacement of
__uint8_t by 0.

[Bug c/90081] stdint constant macros evaluating to wrong type

2019-04-13 Thread msebor at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90081

Martin Sebor  changed:

   What|Removed |Added

URL||http://www.open-std.org/jtc
   ||1/sc22/wg14/www/docs/summar
   ||y.htm#dr_456
 CC||msebor at gcc dot gnu.org

--- Comment #3 from Martin Sebor  ---
UINT8_C(-5) isn't valid but expanding the macros to their arguments isn't
conforming either.  C11 DR #456 suggests compiler magic is necessary to make
the macros correct:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/summary.htm#dr_456 (Also see
C99 DR 209: http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_209.htm).

[Bug c/90081] stdint constant macros evaluating to wrong type

2019-04-13 Thread bafap5 at yahoo dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90081

--- Comment #2 from Guy Perfect  ---
The issue is not resolved based on the merits of the out-of-range values used
in the earlier examples. Type resolution still fails in the current
implementation, as demonstrated below:

  int x = sizeof ((int8_t) 5); /* Correct, gives 1 */
  int y = sizeof (INT8_C(5));  /* Incorrect, gives 4 */

In this case, INT8_C is required to evaluate to type int_least8_t, which cannot
be larger than the smallest integer type able to represent the range of the
type int8_t:

"The typedef name int_least N _t designates a signed integer type with a width
of at least N, such that no signed integer type with lesser size has at least
the specified width."

int8_t can be represented exactly using 1 byte, as shown by the cast. For the
sizeof test to give 4 on the macro demonstrates that the macro is implemented
incorrectly.

A cast is still strongly encouraged (if not necessary) in order for these
macros to be compliant with the stdint.h specification.

[Bug c/90081] stdint constant macros evaluating to wrong type

2019-04-13 Thread sch...@linux-m68k.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90081

Andreas Schwab  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |INVALID

--- Comment #1 from Andreas Schwab  ---
7.20.4#2 The argument in any instance of these macros shall be an unsuffixed
integer constant (as defined in 6.4.4.1) with a value that does not exceed the
limits for the corresponding type.