x86 interrupt attribute

2016-01-18 Thread Wink Saville
What is the status of the x86 interrupt attribute patch?

One of the last references I see is here and an attempt to update the
middle-end here.

-- Wink


Re: x86 interrupt attribute

2016-01-18 Thread Wink Saville
It looks like it will be awhile before its included, what's your guess
on when stage1 will commence for GCC 7?

About how often will you be rebasing hjl/interrupt/stage1 onto master?

On Mon, Jan 18, 2016 at 9:47 AM H.J. Lu  wrote:
>
> On Mon, Jan 18, 2016 at 9:39 AM, Wink Saville  wrote:
> > What is the status of the x86 interrupt attribute patch?
> >
> > One of the last references I see is here and an attempt to update the
> > middle-end here.
> >
> > -- Wink
>
> You can try hjl/interrupt/stage1 branch in git repo, which is queued for
> GCC 7.
>
> --
> H.J.


Compiling with -m64 using attribute interrupt emits IRET not IRETQ

2016-01-28 Thread Wink Saville
I using hjl/interrupt/gcc-5-branch and my program is crashing when I
issue an INT xx. The problem appears to me to be that using
__attribute__ ((interrupt)) causes the a IRET to be emitted when an
IRETQ should be emitted. Below is my trivial do nothing main.c which I
compile with and then use objdump to view the assembler source.

I compiled x86_64-unknown-elf- using crosstool-ng, could that be a problem?

$ cat main.c
typedef unsigned long u64;

typedef struct intr_frame {
  u64 ip;
  u64 cs;
  u64 flags;
  u64 sp;
  u64 ss;
} intr_frame;

__attribute__ ((interrupt))
void ih(struct intr_frame* frame) {
}

void main(void) {
}

$ x86_64-unknown-elf-gcc -c main.c -o main.o -m64
$ x86_64-unknown-elf-objdump -d main.o

main.o: file format elf64-x86-64


Disassembly of section .text:

 :
   0: 55   push   %rbp
   1: 48 89 e5 mov%rsp,%rbp
   4: 50   push   %rax
   5: 48 8d 45 08   lea0x8(%rbp),%rax
   9: 48 89 45 f0   mov%rax,-0x10(%rbp)
   d: 90   nop
   e: 58   pop%rax
   f: 5d   pop%rbp
  10: cf   iret

0011 :
  11: 55   push   %rbp
  12: 48 89 e5 mov%rsp,%rbp
  15: 90   nop
  16: 5d   pop%rbp
  17: c3   retq


Manipulating bit fields is behaving inconsistently

2016-02-17 Thread Wink Saville
When I shift a bit field in an expression small bit fields behave
one way and large bit fields another. I'm using gcc 5.3.0 on Arch Linux:

$ gcc --version
gcc (GCC) 5.3.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


I've created the following example:

#include 

struct fields {
  long long unsigned f0:12;
  long long unsigned f1:52;
} __attribute__((__packed__));

struct fields x = { .f0 = 0xFFF, .f1 = 0xF };

long long unsigned g0;
long long unsigned g1;

void main(void) {
  g0 = x.f0 << 1;
  g1 = x.f1 << 1;

  printf("x.f0=0x%llx\n", x.f0);
  printf("  g0=0x%llx expect 0x1ffe\n", g0);
  printf("x.f1=0x%llx\n", x.f1);
  printf("  g1=0x%llx expect 0x1e\n", g1);
}

The output is:

$ gcc -m64 main.c -o main ; ./main
x.f0=0xfff
  g0=0x1ffe expect 0x1ffe
x.f1=0xf
  g1=0xe expect 0x1e

As you can see when shifting the f0, which is 12 bits, the
most significant bit it is seen in the result. But when shifting f1,
which is 52 bits, it is lost.

Looking at the generated code the difference in output is
because in g0 = x.f0 << 1 the and operation is done before the "shift left"
using add %eax, %eax. Where as with g1 = x.f1 << 1 the and operation
is done after the "shift left" using add %rax, %rax".

00400506 :
  400506: 55   push   %rbp
  400507: 48 89 e5 mov%rsp,%rbp
  40050a: 0f b7 05 f7 04 20 00 movzwl 0x2004f7(%rip),%eax# 600a08 
  400511: 66 25 ff 0f   and$0xfff,%ax
  400515: 0f b7 c0 movzwl %ax,%eax
  400518: 01 c0 add%eax,%eax
  40051a: 48 98 cltq
  40051c: 48 89 05 fd 04 20 00 mov%rax,0x2004fd(%rip)# 600a20 
  400523: 48 8b 05 de 04 20 00 mov0x2004de(%rip),%rax# 600a08 
  40052a: 48 c1 e8 0c   shr$0xc,%rax
  40052e: 48 01 c0 add%rax,%rax
  400531: 48 ba ff ff ff ff ff movabs $0xf,%rdx
  400538: ff 0f 00
  40053b: 48 21 d0 and%rdx,%rax
  40053e: 48 89 05 d3 04 20 00 mov%rax,0x2004d3(%rip)# 600a18 


It feels wrong that they would behave differently, is this really
correct behavior?

-- Wink


Re: Manipulating bit fields is behaving inconsistently

2016-02-18 Thread Wink Saville
You've convinced me that this isn't a bug, but I assume you'd agree
its weird at best. I tested it with clang and it works as I'd expect:

$ make
clang -x c -m64 -O3 -Wall -o test.o -c test.c
objdump -d test.o > test.txt
clang -m64 -O3 -Wall test.o -o test
wink@wink-desktop:~/prgs/large_fields_are_odd
$ ./test
x.f0=0xfff
  g0=0x1ffe expect 0x1ffe
x.f1=0xf
  g1=0x1e expect 0x1e

Here is the make file:

CC = clang
CFLAGS = -m64 -O3 -Wall

all: test

test.o: test.c
$(CC) -x c $(CFLAGS) -o test.o -c test.c
objdump -d test.o > test.txt

test: test.o
$(CC) $(CFLAGS) test.o -o test

clean:
rm -f test test.o test.txt


Do you think gcc should change?

On Thu, Feb 18, 2016 at 2:52 AM, Bernd Edlinger
 wrote:
> Hi,
>
>> struct fields {
>>   long long unsigned f0:12;
>>   long long unsigned f1:52;
>> } __attribute__((__packed__));
>
> the C99 standard ISO/IEC 9899 forbids this type:
>
> 6.7.2.1 Structure and union specifiers
>
> 4 A bit-field shall have a type that is a qualified or unqualified version of 
> _Bool, signed int,
>unsigned int, or some other implementation-defined type.
>
> The C standard simply does not promote the bit-field value to any type larger 
> than int or
> unsigned int.
>
> GCC chooses to do the larger than int computations in an artificial 52-bit 
> type, but it is a
> non-standard extension.
>
> And if you compile your example with -Wall you'll see the problem:
>
> gcc -m32 -O3 -Wall  test.c
> test.c: In function 'main':
> test.c:17:21: warning: format '%llx' expects argument of type 'long long 
> unsigned int', but argument 2 has type 'int' [-Wformat=]
>printf("x.f0=0x%llx\n", x.f0);
>  ^
> test.c:19:21: warning: format '%llx' expects argument of type 'long long 
> unsigned int', but argument 2 has type 'long long unsigned int:52' [-Wformat=]
>printf("x.f1=0x%llx\n", x.f1);
>  ^
>
> so especially the first warning is no joke:
>
> ./a.out
> x.f0=0x80497b40fff
>   g0=0x1ffe expect 0x1ffe
> x.f1=0xf
>   g1=0xe expect 0x1e
>
>
> OTOH that is perfectly OK for C++:
>
> gcc -x c++ -m32 -O3 -Wall  test.c
>
> ./a.out
> x.f0=0xfff
>   g0=0x1ffe expect 0x1ffe
> x.f1=0xf
>   g1=0x1e expect 0x1e
>
>
> Regards
> Bernd.


Re: Manipulating bit fields is behaving inconsistently

2016-02-19 Thread Wink Saville
What is the process for a patch with a new option to allow a different behavior?


How to use _Generic with bit-fields

2016-02-19 Thread Wink Saville
I'm using gcc 5.3.0:

$ gcc --version
gcc (GCC) 5.3.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


And I've tried to use _Generic to print the type of a bit field but
the compiler fails with:

$ make
gcc -Wall -std=c11 -o test.o -c test.c
test.c: In function ‘main’:
test.c:8:35: error: ‘_Generic’ selector of type ‘unsigned char:2’ is
not compatible with any association
 #define type_to_str(__x) _Generic((__x), \
   ^
test.c:17:18: note: in expansion of macro ‘type_to_str’
   printf("%s\n", type_to_str(b.f1));
  ^
Makefile:7: recipe for target 'test.o' failed
make: *** [test.o] Error 1
bash: ./test: No such file or directory


The test program is:

$ cat test.c
#include 

struct bits {
  unsigned char f0;
  unsigned char f1:2;
};

#define type_to_str(__x) _Generic((__x), \
  unsigned char : "unsigned char")

int main(void) {
  struct bits b = { .f0 = 255, .f1 = 3 };

  printf("%d\n", b.f0);
  printf("%s\n", type_to_str(b.f0));
  printf("%d\n", b.f1);
  printf("%s\n", type_to_str(b.f1));

  return 0;
}

And the Makefile is:

$ cat Makefile
CC = gcc
CFLAGS = -Wall -std=c11

all: test

test.o: test.c
$(CC) $(CFLAGS) -o test.o -c test.c

test: test.o
$(CC) $(CFLAGS) test.o -o test

clean:
rm -f test test.o test.txt


My type_to_str macro seems correct, as all is well if I comment out the last
printf:

$ cat test.c
#include 

struct bits {
  unsigned char f0;
  unsigned char f1:2;
};

#define type_to_str(__x) _Generic((__x), \
  unsigned char : "unsigned char")

int main(void) {
  struct bits b = { .f0 = 255, .f1 = 3 };

  printf("%d\n", b.f0);
  printf("%s\n", type_to_str(b.f0));
  printf("%d\n", b.f1);
  //printf("%s\n", type_to_str(b.f1));

  return 0;
}


It then compiles and runs successfully:

$ make
gcc -Wall -std=c11 -o test.o -c test.c
gcc -Wall -std=c11 test.o -o test
$ ./test
255
unsigned char
3


How do I create a type association for a bit field?


Re: Manipulating bit fields is behaving inconsistently

2016-02-19 Thread Wink Saville
The two links in msg00156.html point to single emails and the
formatting is odd, such as in 13560.txt:

  i =3D =5FGeneric(st.bf,

Is there a way to look at the actual email thread using a browser or
some other means?


On Fri, Feb 19, 2016 at 9:30 AM, Joseph Myers  wrote:
> See the references I gave in
> .
>
> --
> Joseph S. Myers
> jos...@codesourcery.com


Re: How to use _Generic with bit-fields

2016-02-21 Thread Wink Saville
I've tried you hack, but it doesn't work with "long bit fields". Also,
I've run into another problem. Instead of using unsigned char for
the bit field I changed it to a long unsigned int:33 and now I can't
print it without a warning.

Here is my Makefile:

CC = gcc
O = 3
X = c
STD = c11

CFLAGS = -m64 -Wall -std=$(STD)

all: test

test.o: test.c
$(CC) -x $(X) -O$(O) $(CFLAGS) -o test.o -c test.c
objdump -d test.o > test.txt

test: test.o
$(CC) $(CFLAGS) test.o -o test

clean:
rm -f test test.o test.txt

Here is the test:

#include 

struct big_bit_fields {
  long unsigned int b33:33;
} __attribute__((__packed__));

_Static_assert(sizeof(struct big_bit_fields) == 5,
L"big_bit_fields is not 5 bytes");


#define type_to_str(__x) _Generic((0)?(__x):(__x), \
  _Bool : "_Bool", \
  char : "char", \
  signed char : "unsigned char", \
  unsigned char : "unsigned char", \
  short int : "short int", \
  unsigned short int: "unsigned short int", \
  int : "int", \
  unsigned int : "unsigned int", \
  long int : "long int", \
  long unsigned int : "long unsigned int", \
  long long int : "long long int", \
  long long unsigned int : "long long unsigned int", \
  default : "unknown type")

int main(void) {
  struct big_bit_fields bbf = { .b33 = 0x1 };

  printf("bbf.b33=0x%lx\n", bbf.b33);
  printf("   type=%s\n", type_to_str(bbf.b33));
  printf("   <<1 =0x%016lx\n", bbf.b33 << 1);
  printf("  (ull)<<1 =0x%016lx\n", (long unsigned int)bbf.b33 << 1);

  return 0;
}


Here the compile and run:

$ make clean ; make ; ./test
rm -f test test.o test.txt
gcc -x c -O3 -m64 -Wall -std=c11 -o test.o -c test.c
test.c: In function ‘main’:
test.c:44:10: warning: format ‘%lx’ expects argument of type ‘long
unsigned int’, but argument 2 has type ‘long unsigned int:33’
[-Wformat=]
   printf("bbf.b33=0x%lx\n", bbf.b33);
  ^
test.c:46:10: warning: format ‘%lx’ expects argument of type ‘long
unsigned int’, but argument 2 has type ‘long unsigned int:33’
[-Wformat=]
   printf("   <<1 =0x%016lx\n", bbf.b33 << 1);
      ^
objdump -d test.o > test.txt
gcc -m64 -Wall -std=c11 test.o -o test
bbf.b33=0x1
   type=unknown type
   <<1 =0x0001fffe
  (ull)<<1 =0x0003fffe




On Fri, Feb 19, 2016 at 1:35 PM, Martin Sebor  wrote:
> On 02/19/2016 11:25 AM, Wink Saville wrote:
>>
>> I'm using gcc 5.3.0:
>>
>> $ gcc --version
>> gcc (GCC) 5.3.0
>> Copyright (C) 2015 Free Software Foundation, Inc.
>> This is free software; see the source for copying conditions.  There is NO
>> warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
>> PURPOSE.
>>
>>
>> And I've tried to use _Generic to print the type of a bit field but
>> the compiler fails with:
>>
>> $ make
>> gcc -Wall -std=c11 -o test.o -c test.c
>> test.c: In function ‘main’:
>> test.c:8:35: error: ‘_Generic’ selector of type ‘unsigned char:2’ is
>> not compatible with any association
>>   #define type_to_str(__x) _Generic((__x), \
>> ^
>> test.c:17:18: note: in expansion of macro ‘type_to_str’
>> printf("%s\n", type_to_str(b.f1));
>>^
>> Makefile:7: recipe for target 'test.o' failed
>> make: *** [test.o] Error 1
>> bash: ./test: No such file or directory
>>
>>
>> The test program is:
>>
>> $ cat test.c
>> #include 
>>
>> struct bits {
>>unsigned char f0;
>>unsigned char f1:2;
>> };
>>
>> #define type_to_str(__x) _Generic((__x), \
>>unsigned char : "unsigned char")
>>
>> int main(void) {
>>struct bits b = { .f0 = 255, .f1 = 3 };
>>
>>printf("%d\n", b.f0);
>>printf("%s\n", type_to_str(b.f0));
>>printf("%d\n", b.f1);
>>printf("%s\n", type_to_str(b.f1));
>>
>>return 0;
>> }
>>
> ...
>>
>> How do I create a type association for a bit field?
>
>
> I suspect this falls under the set of issues that fall under bug
> 65471 - type interpretation in _Generic.  The C language rules
> for _Generic aren't completely clear about what conversions are
> to take place.  It would be helpful if you could your test case
> to the bug to make sure the bitfield case is considered when
> the issue is discussed by the C committee.
>
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65471
>
> The only idea for a workaround that comes to mind is to trick GCC
> into forgetting that it's a bit-field.  This hack seems to work:
>
>   #define type_to_str(__x) _Generic((0)?(__x):(__x), \
>
> Martin
>


Re: How to use _Generic with bit-fields

2016-02-22 Thread Wink Saville
I understand "long" bit fields are in ISO, but its a gcc extension so
it would seem it should play nice with as much of the language as
possible.

It seems the root of the problem here is the length encoding
in the type, why does gcc do that, does the standard
require it?

On Mon, Feb 22, 2016 at 3:48 PM, Joseph Myers  wrote:
> On Mon, 22 Feb 2016, Wink Saville wrote:
>
>> What about printing of "long" bit fields? I wonder if there should be an
>> option which indicates that bit field types should not include their length.
>
> "long" bit-fields aren't even guaranteed by ISO C to be supported at all;
> portable code must avoid them.  The portable way to print values of
> arbitrary integer types is to cast to intmax_t / uintmax_t and then use
> corresponding formats; that works fine with such bit-fields as well as
> normal types.
>
> --
> Joseph S. Myers
> jos...@codesourcery.com


Re: How to use _Generic with bit-fields

2016-02-22 Thread Wink Saville
I'm sorry I meant:

I understand "long" bit lengths are NOT in ISO, "



On Mon, Feb 22, 2016 at 4:06 PM, Wink Saville  wrote:
> I understand "long" bit fields are in ISO, but its a gcc extension so
> it would seem it should play nice with as much of the language as
> possible.
>
> It seems the root of the problem here is the length encoding
> in the type, why does gcc do that, does the standard
> require it?
>
> On Mon, Feb 22, 2016 at 3:48 PM, Joseph Myers  wrote:
>> On Mon, 22 Feb 2016, Wink Saville wrote:
>>
>>> What about printing of "long" bit fields? I wonder if there should be an
>>> option which indicates that bit field types should not include their length.
>>
>> "long" bit-fields aren't even guaranteed by ISO C to be supported at all;
>> portable code must avoid them.  The portable way to print values of
>> arbitrary integer types is to cast to intmax_t / uintmax_t and then use
>> corresponding formats; that works fine with such bit-fields as well as
>> normal types.
>>
>> --
>> Joseph S. Myers
>> jos...@codesourcery.com


Re: How to use _Generic with bit-fields

2016-02-22 Thread Wink Saville
Joseph,

Thanks for the unary + suggestion.

It definitely makes sense that the bit field length must be known for
handling things like assignments, but it doesn't have to be part of
the type signature.


Martin,

I've updated bug 65471: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65471


I created a simpler test program:

$ cat test.c
#include 

struct S {
  int b0:4;
  unsigned int b1:4;
  unsigned long long int b33:33;
};

#define type2str(__x) _Generic((__x), \
  int : "int", \
  unsigned int : "unsigned int", \
  unsigned long long int : "unsigned long long int", \
  default : "unknown")

int main(void) {
  struct S s = { .b0=3, .b1=4, .b33=0x1 };
  (void)s; // Not used

   // gcc | clang output
  printf("type2str(s.b0):  %s\n", type2str(s.b0)); // unknown | int
  printf("type2str(s.b1):  %s\n", type2str(s.b1)); // unknown | unsigned int
  printf("type2str(s.b33): %s\n", type2str(s.b33));// unknown |
unsigned long long int

  return 0;
}

$ cat Makefile
CC = gcc
O = 3
STD = c11
M = 32

test: test.c Makefile
$(CC) -O$(O) -m$(M) -Wall -std=$(STD) test.c -o test

clean:
rm -f test



And ran it on gcc and clang

$ make clean ; make CC=gcc ; ./test
rm -f test
gcc -O3 -m32 -Wall -std=c11 test.c -o test
type2str(s.b0):  unknown
type2str(s.b1):  unknown
type2str(s.b33): unknown

$ make clean ;make CC=clang ; ./test
rm -f test
clang -O3 -m32 -Wall -std=c11 test.c -o test
type2str(s.b0):  int
type2str(s.b1):  unsigned int
type2str(s.b33): unsigned long long int


-- Wink


On Mon, Feb 22, 2016 at 4:58 PM, Joseph Myers  wrote:
> On Mon, 22 Feb 2016, Martin Sebor wrote:
>
>> for the C standard not to support it.  (The problem is simply that
>> wording that specifies the feature was poorly chosen and GCC seems
>> to follow it a bit too strictly, and to the detriment of usability.)
>
> The wording for bit-fields, although unclear in places, elegantly
> addresses all the issues with what the semantics of assignment to
> bit-fields are (including e.g. allowing an instruction for conversion of
> floating-point to 16-bit integer, complete with raising exceptions for
> out-of-range values, to be used to convert to int:16, rather than
> requiring a conversion to int and subsequent conversion from int to
> int:16), with none of the duplication that would be involved if bit-fields
> had the underlying types and so semantics for conversions needed to be
> specified separately.  It also naturally means that e.g. unsigned long:1
> promotes to int in expressions, by the normal rules for promotions.
>
>> $ cat z.c && /home/msebor/build/gcc-trunk-svn/gcc/xgcc
>> -B/home/msebor/build/gcc-trunk-svn/gcc -Wall -Wextra -Wpedantic -xc z.c
>> struct S { unsigned i: 31; } s;
>> int i = _Generic (s.i, unsigned: 1);
>> z.c:2:19: error: ‘_Generic’ selector of type ‘unsigned int:31’ is not
>> compatible with any association
>>  int i = _Generic (s.i, unsigned: 1);
>>^
>
> That can be avoided simply by using unary + in the controlling expression
> of _Generic (just as using unary + will avoid an error from sizeof, if you
> want to be able to apply that to expressions that might be bit-fields) -
> or any of the other techniques for achieving promotions of selected types.
>
> You can't use bit-fields with sizeof, or with unary &, or in GNU C with
> typeof.  I think extending this constraint to _Generic - meaning you need
> to use a trick such as unary + when a bit-field might occur there - is
> consistent with the peculiar position of bit-fields in C as not quite
> normal objects or types (and consistent with how _Generic is intended for
> certain limited kinds of overloading such as , not for
> arbitrarily expressive logic on types, cf. the rejection of overloading on
> qualifiers).  If someone uses e.g. unsigned int:8 as the controlling
> expression of _Generic, it's hardly clear whether a selection for unsigned
> char (a type with the same set of values), unsigned int (the declared type
> ignoring width) or int (the type resulting from the integer promotions)
> would be the most useful selection.
>
> --
> Joseph S. Myers
> jos...@codesourcery.com


Re: How to use _Generic with bit-fields

2016-02-24 Thread Wink Saville
See comment on (c) below

On Wed, Feb 24, 2016 at 1:53 PM Joseph Myers  wrote:
>
> On Wed, 24 Feb 2016, Martin Sebor wrote:
>
> > > That can be avoided simply by using unary + in the controlling expression
> > > of _Generic (just as using unary + will avoid an error from sizeof, if you
> > > want to be able to apply that to expressions that might be bit-fields) -
> > > or any of the other techniques for achieving promotions of selected types.
> >
> > Unfortunately, the + n trick is far too limited to be generally
> > usable.  Since GCC allows bit-fields of other integers types
> > besides those described by the standard (e.g., long long), the
> > plus expression would have to be converted to the widest possible
> > type (e.g., by (x + 0LL)) which would defeat the purpose of
> > _Generic.  The trick of course work at all for type-generic
> > macro intended to also accept non- scalar arguments.
>
> There are lots of variants of the trick (including the conditional
> expression one), depending on which types you care about distinguishing
> and which are valid arguments to the macro.  If you want, you can even
> distinguish each bit-field width wider than int individually using typeof,
> via writing expressions with typeof to determine the width of the type.
>
> I suspect many attempts to use _Generic with non-arithmetic types would
> run into usability problems in practice because every expression in the
> generic association list must still pass the Constraints whatever the type
> of the controlling expression - so you can select a function name based on
> that type, but putting more complicated expressions directly inside
> _Generic would be problematic in many cases if a wide range of types is to
> be allowed.
>
> There is a basic question: is _Generic supposed to be arbitrarily
> expressive, or is it meant to cover cases like ?  The answer in
> the context of questions about qualifiers and array-to-pointer decay was
> that it is meant to cover cases like , not to be arbitrarily
> expressive for hypothetical cases.  Maximal expressiveness would allow
> distinguishing all bit-field widths, but that would fall down on
> usability.
>
> Integer types narrower than int are effectively second-class entities in
> C; you can't write constants of those types, for example, and they get
> promoted before used in arithmetic or being passed in variable arguments;
> while you *can* select on them with _Generic, the utility of doing so may
> be limited.  Bit-fields are effectively third-class entities, and
> bit-fields with implementation-defined declared types other than int or
> signed int or unsigned int are fourth-class (not required by the standard
> at all, and have their own problems of specification - and the final
> choice for DR#315 was to leave pretty much everything about such
> bit-fields implementation-defined - see the minutes for Portland 2006,
> London 2007, Kona 2007).
>
> > GCC's handling of bit-fields in __typeof__  is also a problem
> > and causes bugs in .  For example, the following is
> > rejected by GCC (with not just one but 42 errors) as a result:
> >
> >   struct S { unsigned b: 31; } s;
> >   carg (s.b);
>
> That should be reported as an ordinary bug in , that can easily
> be addressed by using unary + so that typeof isn't applied to a bit-field
> ( treats all integer types the same and non-arithmetic types are
> irrelevant to it, so unary + is absoletely fine there).
>
> > If it isn't clear it should be brought up in WG14 and clarified.
> > It's clear enough in C++ for bit-fields to be used as arguments
> > to overloaded functions or function templates.  I can't imagine
>
> C++ has long diverged from C regarding bit-fields (allowing other declared
> types, allowing widths wider than the width of the underlying type, now
> requiring plain int bit-fields to be signed, ...).  Whereas C has its line
> of textual history going back to various C90 DRs and showing that:
>
> (a) whether a bit-field width counts of part of the type doesn't generally
> matter within the standard except for integer promotions, so can safely be
> left unspecified with just special wording for promotions (modulo the new
> _Generic issue);
>
> (b) everything about such matters for bit-fields of nonstandard types can
> be left implementation-defined;
>
> (c) nothing defines semantics of conversion of out-of-range values to
> bit-fields other than treating the width as part of the type (or in the
> case of _Bool bit-fields, having the special wording to make it explicit
> that those have the semantics of _Bool not the semantics of an ordinary
> unsigned integer type with the specified number of bits).


I don't see where in the standard it says the width of a bit field is
part of the type.
I see In Section 6.7.2.1 paragraphs 9, 10, 11, 12 requires the compiler to know
the width, but I don't see where the width is part of the type.

Could you point me to the appropriate paragraph(s)?

-- wink

>
>
> --
> Joseph S. Myers
> jo

Re: How to use _Generic with bit-fields

2016-02-24 Thread Wink Saville
On Wed, Feb 24, 2016 at 3:38 PM, Joseph Myers  wrote:
> On Wed, 24 Feb 2016, Wink Saville wrote:
>
>> > (c) nothing defines semantics of conversion of out-of-range values to
>> > bit-fields other than treating the width as part of the type (or in the
>> > case of _Bool bit-fields, having the special wording to make it explicit
>> > that those have the semantics of _Bool not the semantics of an ordinary
>> > unsigned integer type with the specified number of bits).
>>
>>
>> I don't see where in the standard it says the width of a bit field is
>> part of the type.
>> I see In Section 6.7.2.1 paragraphs 9, 10, 11, 12 requires the compiler to 
>> know
>> the width, but I don't see where the width is part of the type.
>>
>> Could you point me to the appropriate paragraph(s)?
>
> If you look at the London 2007 minutes
> <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1267.pdf> you'll see
> that at that time this was intended to be deliberately ambiguous, to
> support both C++ practice and the longstanding C intent as expressed in
> the responses to various C90 DRs (the difference, at that time, only
> mattering for implementation-defined bit-field types).
>
> The "interpreted as having a signed or unsigned integer type consisting of
> the specified number of bits" (paragraph 10), if applied for the purposes
> of interpreting other references to types in C11, has consequences
> including: (i) conversions to store a value in a bit-field follow the same
> rules as conversions to a normal integer type, (ii) a bit-field with width
> less than that of int also has integer conversion rank less than that of
> int, and so promotes to int under the integer promotions (even if the
> declared type is wider than int).

I found this very surprising, but the standard does seem to require this.

>  (It also has the less intuitive
> consequences regarding bit-field types escaping from their bit-field
> context, as discussed in the present thread and elsewhere.)
>
> Without it being part of the type, making long:1 promote to int (as in
> C++) not long would require changes to the wording on promotions, and
> separate wording would be needed to make the results of assignments clear
> (and I'm not convinced that C++ has such wording in all cases where it is
> needed).

Clang doesn't seem to need to have the width as part of the type. And by not
having it as part of the type _Generic works as expected on clang but doesn't
work on gcc.

Further more things like printing of "big" bit fields such as
unsigned long long int b:33 doesn't issue any warnings with -Wall on clang
but does on gcc. Also, the shifting weirdness doesn't occur on clang.
>From my perspective, as a user, I think these behaviors are gcc bugs.

If someone were to supply a patch that changed the behavior to match
what clang and apparently other compilers are doing, would you be likely
to accept it?

-- Wink

> --
> Joseph S. Myers
> jos...@codesourcery.com


Re: How to use _Generic with bit-fields

2016-02-25 Thread Wink Saville
Thanks for the info. What I'll probably do is file a bug and reply to this
thread and the other one when I do.


On Thu, Feb 25, 2016, 2:50 PM Joseph Myers  wrote:
>
> On Wed, 24 Feb 2016, Wink Saville wrote:
>
> > Further more things like printing of "big" bit fields such as
> > unsigned long long int b:33 doesn't issue any warnings with -Wall on clang
>
> Of course, printing such a bit-field with %llu etc. isn't fully portable
> even with the C++ semantics for bit-field types.  With the C++ semantics,
> if int is 34 bits or more then it gets promoted to int; otherwise, if
> unsigned int is 33 bits or more then it gets promoted to unsigned int.  So
> as with many cases of using variadic functions, you need to include a cast
> to get the desired types.  It just so happens it's hard for warnings to
> tell how portable you want the code to be, or to tell whether an
> unportable format for a type was e.g. autoconf-detected to be correct.
>
> > If someone were to supply a patch that changed the behavior to match
> > what clang and apparently other compilers are doing, would you be likely
> > to accept it?
>
> Not without a clear direction from WG14 to require the C++ rules (in which
> case conditionals on the C standard version would be appropriate, given
> the previous direction from the C90 DRs).  You'd need to track the
> declared type for each bit-field alongside the reduced-width type, apply
> C++-style promotions and conversions to the declared type for relevant
> rvalue uses, and handle the types appropriately in _Generic and typeof -
> other changes could be needed if e.g. conversion from floating-point to
> bit-fields were defined to convert to the declared type and then convert
> from that to the bit-field.  (A narrower direction only defining types in
> _Generic might still require tracking declared types but not require so
> many other changes.)
>
> --
> Joseph S. Myers
> jos...@codesourcery.com