Mir

Merge lp:~afrantzis/mir/fix-gcc-4.9-build into lp:mir

Proposed by Alexandros Frantzis
Status: Merged
Approved by: Kevin DuBois
Approved revision: no longer in the source branch.
Merged at revision: 1757
Proposed branch: lp:~afrantzis/mir/fix-gcc-4.9-build
Merge into: lp:mir
Diff against target: 34 lines (+3/-3)
2 files modified
src/shared/graphics/android/syncfence.cpp (+1/-1)
tests/unit-tests/graphics/android/test_sync_fence.cpp (+2/-2)
To merge this branch: bzr merge lp:~afrantzis/mir/fix-gcc-4.9-build
Reviewer Review Type Date Requested Status
Kevin DuBois (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Alan Griffiths Approve
Review via email: mp+226138@code.launchpad.net

Commit message

android,tests: Fix g++ 4.9 build

It seems that g++-4.9 has become more aggressive about constant folding of
expressions that use sizeof(), thus triggering warnings/errors related to
constant overflows that didn't occur with g++-4.8.

For example, g++-4.8 warns about overflowing i3, but not i4, whereas g++-4.9
warns about both i3 and i4:

#define VALUE1 0x70000000UL
#define VALUE2 (VALUE1 >> sizeof(unsigned char))
#define VALUE3 0x80000000UL
#define VALUE4 (VALUE1 << sizeof(unsigned char))

int main()
{
    int i1 = VALUE1;
    int i2 = VALUE2;
    int i3 = VALUE3;
    int i4 = VALUE4;
}

This affects our ioctl() wrapper calls because we use 'int' for the request
parameter, whereas the request numbers produced by the kernel macros (using
sizeof() in the calculation) are 'unsigned long'. This MP fixes the problem by
casting the request numbers to 'int', which is a safe conversion since the
request numbers are constrained to 32 bits by design.

Note that we don't have a problem with all ioctl request numbers, although they
are produced by the same set of macros, because almost all of them don't have
the high bit set (like VALUE2 above) and don't trigger the overflow error. The
one we have a problem with, SYNC_IOC_MERGE, has the high bit set (like VALUE4
above).

Also note that the glibc ioctl() function signature uses 'unsigned long'
instead of 'int' for the request number. So, alternatively, we could fix the
problem by changing our wrappers to use 'unsigned long', too. However, the
glibc signature goes against POSIX and there have been discussions about
switching it back. See https://sourceware.org/bugzilla/show_bug.cgi?id=14362 .

Description of the change

android,tests: Fix g++ 4.9 build

It seems that g++-4.9 has become more aggressive about constant folding of
expressions that use sizeof(), thus triggering warnings/errors related to
constant overflows that didn't occur with g++-4.8.

For example, g++-4.8 warns about overflowing i3, but not i4, whereas g++-4.9
warns about both i3 and i4:

#define VALUE1 0x70000000UL
#define VALUE2 (VALUE1 >> sizeof(unsigned char))
#define VALUE3 0x80000000UL
#define VALUE4 (VALUE1 << sizeof(unsigned char))

int main()
{
    int i1 = VALUE1;
    int i2 = VALUE2;
    int i3 = VALUE3;
    int i4 = VALUE4;
}

This affects our ioctl() wrapper calls because we use 'int' for the request
parameter, whereas the request numbers produced by the kernel macros (using
sizeof() in the calculation) are 'unsigned long'. This MP fixes the problem by
casting the request numbers to 'int', which is a safe conversion since the
request numbers are constrained to 32 bits by design.

Note that we don't have a problem with all ioctl request numbers, although they
are produced by the same set of macros, because almost all of them don't have
the high bit set (like VALUE2 above) and don't trigger the overflow error. The
one we have a problem with, SYNC_IOC_MERGE, has the high bit set (like VALUE4
above).

Also note that the glibc ioctl() function signature uses 'unsigned long'
instead of 'int' for the request number. So, alternatively, we could fix the
problem by changing our wrappers to use 'unsigned long', too. However, the
glibc signature goes against POSIX and there have been discussions about
switching it back. See https://sourceware.org/bugzilla/show_bug.cgi?id=14362 .

To post a comment you must log in.
Revision history for this message
Alan Griffiths (alan-griffiths) wrote :
review: Approve
Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

Note that in order to see the warning/error the "-pedantic" flag is needed.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Kevin DuBois (kdub) wrote :

lgtm

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/shared/graphics/android/syncfence.cpp'
2--- src/shared/graphics/android/syncfence.cpp 2014-03-06 06:05:17 +0000
3+++ src/shared/graphics/android/syncfence.cpp 2014-07-09 13:57:11 +0000
4@@ -65,7 +65,7 @@
5 {
6 //both fences were valid, must merge
7 struct sync_merge_data data { merge_fd, "mirfence", infinite_timeout };
8- ops->ioctl(fence_fd, SYNC_IOC_MERGE, &data);
9+ ops->ioctl(fence_fd, static_cast<int>(SYNC_IOC_MERGE), &data);
10 ops->close(fence_fd);
11 ops->close(merge_fd);
12 fence_fd = data.fence;
13
14=== modified file 'tests/unit-tests/graphics/android/test_sync_fence.cpp'
15--- tests/unit-tests/graphics/android/test_sync_fence.cpp 2014-03-06 06:05:17 +0000
16+++ tests/unit-tests/graphics/android/test_sync_fence.cpp 2014-07-09 13:57:11 +0000
17@@ -107,7 +107,7 @@
18
19 struct sync_merge_data expected_data_in { dummy_fd2, "name", 0 };
20
21- EXPECT_CALL(*mock_fops, ioctl(dummy_fd, SYNC_IOC_MERGE, MergeMatches(expected_data_in)))
22+ EXPECT_CALL(*mock_fops, ioctl(dummy_fd, static_cast<int>(SYNC_IOC_MERGE), MergeMatches(expected_data_in)))
23 .Times(1)
24 .WillOnce(Invoke(&setter, &IoctlSetter::merge_setter));
25
26@@ -119,7 +119,7 @@
27 TEST_F(SyncSwTest, sync_merge_with_invalid_fd)
28 {
29 using namespace testing;
30- EXPECT_CALL(*mock_fops, ioctl(dummy_fd, SYNC_IOC_MERGE, _))
31+ EXPECT_CALL(*mock_fops, ioctl(dummy_fd, static_cast<int>(SYNC_IOC_MERGE), _))
32 .Times(0);
33
34 mga::SyncFence fence1(mock_fops, invalid_fd);

Subscribers

People subscribed via source and target branches