Bug 17679 - Can't use htole*, htobe*, __bswap* functions in static/global context
Summary: Can't use htole*, htobe*, __bswap* functions in static/global context
Status: RESOLVED INVALID
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-12-04 15:31 UTC by Dan Streetman
Modified: 2014-12-12 14:05 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments
Patch to add tests to tst-bswap and tst-endian (1.07 KB, patch)
2014-12-04 15:33 UTC, Dan Streetman
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dan Streetman 2014-12-04 15:31:15 UTC
The current definitions of the __bswap_* macros prevent their use in a static/global context.  For use with constant values, they should be usable even in a global context.
Comment 1 Dan Streetman 2014-12-04 15:33:17 UTC
Created attachment 7996 [details]
Patch to add tests to tst-bswap and tst-endian

This patch adds tests for this bug.  When building, you can clearly see the failure:

In file included from ../bits/byteswap.h:34:0,
                 from ../string/byteswap.h:24,
                 from ../include/byteswap.h:1,
                 from tst-bswap.c:19:
../bits/byteswap-16.h:26:6: error: braced-group within expression allowed only inside a function
      ({ unsigned short int __bsx = (unsigned short int) (x);        \
      ^
tst-bswap.c:28:28: note: in expansion of macro ‘__bswap_16’
 static __uint16_t swap16 = __bswap_16(0x1234);
                            ^
tst-bswap.c:31:1: error: initializer element is not constant
 static __uint32_t swap32 = __bswap_32(0x12345678);
 ^
tst-bswap.c:34:1: error: initializer element is not constant
 static __uint64_t swap64 = __bswap_64(0x1234567890abcdefULL);
 ^
Comment 2 Dan Streetman 2014-12-04 15:37:58 UTC
FYI, I found this bug because the current linux kernel fails to build on BE platforms because of the use of htole16() and htole32() in the setup of a static variable in Documentation/mic/mpssd/mpssd.c; the failure is:

In file included from /usr/include/bits/byteswap.h:34:0,
                 from /usr/include/endian.h:60,
                 from /usr/include/bits/waitstatus.h:64,
                 from /usr/include/stdlib.h:42,
                 from /root/linux/Documentation/mic/mpssd/mpssd.c:23:
/root/linux/Documentation/mic/mpssd/mpssd.c:93:10: error: braced-group within expression allowed only inside a function
   .num = htole16(MIC_VRING_ENTRIES),
          ^
/root/linux/Documentation/mic/mpssd/mpssd.c:119:3: error: initializer element is not constant
   .host_features = htole32(
   ^
Comment 3 Dan Streetman 2014-12-04 15:51:36 UTC
I believe these functions were added via bug 6442.
Comment 4 Andreas Schwab 2014-12-04 15:54:08 UTC
How is that a bug?  C does not allow function calls in file scope.
Comment 5 jsm-csl@polyomino.org.uk 2014-12-04 16:09:22 UTC
I think it should be valid to do e.g.

int a;
void foo (int (*x)[htonl (a)]);

(where [htonl (a)] is equivalent to [*]).  Or, for that matter,

char b[sizeof (htonl (a))];

These certainly aren't the only standard functions / macros defined in a 
way causing problems with that, and maybe a compiler change to allow ({}) 
outside functions (only giving an error if the resulting expression's 
value gets used) would be the best fix.
Comment 6 Andreas Schwab 2014-12-04 16:40:16 UTC
The compiler should allow expression statements in non-evaluated context, but other than that this is not a bug in libc.
Comment 7 Andreas Schwab 2014-12-04 17:16:48 UTC
Constant expressions cannot contain function calls.