Bug 47357 - volatile member function is not treated as volatile
Summary: volatile member function is not treated as volatile
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.5.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-01-19 09:00 UTC by Kenta Yoshimura
Modified: 2011-01-19 10:44 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Kenta Yoshimura 2011-01-19 09:00:13 UTC
When I execute the following test code with '-O2 -msse2' compiler options, it
outputs the wrong value.
I'm expecting that pC[1] will be 2.

operator[](int) is defined as volatile. However v is not treated as volatile.
And I tried (volatile const u &) instead of (const u &) when the casting, but it's not affected.

-- begin test case --
//g++ -O2 -msse2 test.cpp
#include <stdio.h>
#include <stdint.h>
#include <emmintrin.h>

#define NELEM 1

struct int4
{
	__m128i v;

	int4(__m128i a) : v(a) {}

	int4(int a0, int a1, int a2, int a3)
		: v(_mm_setr_epi32(a0, a1, a2, a3)) {}
	
	operator __m128i() const { return v; }

	int operator [](int i) volatile const
	{
		union u {
			__m128i m128;
			int     i32[4];
		};
		
		return ((const u &)v).i32[i];
	}
};

inline int4 operator <<(const int4 & a, const int4 & b)
{ return int4(a[0]<<b[0], a[1]<<b[1], a[2]<<b[2], a[3]<<b[3]); }

__attribute__((noinline)) void shift_left(
	int n, const __m128i a[], const __m128i b[], __m128i c[])
{
	for ( int j = 0; j < n; ++j )
	{
		c[j] = int4(a[j]) << int4(b[j]);
	}
}

int main( int argc, char * argv[] )
{
	__m128i * a = new __m128i[NELEM+1];
	__m128i * b = new __m128i[NELEM+1];
	__m128i * c = new __m128i[NELEM+1];
	
	a = (__m128i *)(-sizeof(*a) & (intptr_t)&a[1]);
	b = (__m128i *)(-sizeof(*b) & (intptr_t)&b[1]);
	c = (__m128i *)(-sizeof(*c) & (intptr_t)&c[1]);
	
	for ( int i = 0; i < NELEM*4; ++i )
	{
		((int *)a)[i] = i;
		((int *)b)[i] = i & 31;
		((int *)c)[i] = 0;
	}

	shift_left(NELEM, a, b, c);
	
	const int * pA = (const int *)a;
	const int * pB = (const int *)b;
	const int * pC = (const int *)c;
	
	for ( int i = 0; i < NELEM*4; ++i )
	{
		printf("%08x << %08x = %08x\n",
			pA[i], pB[i], pC[i]);
	}
}
-- end test case --

-- begin output --
00000000 << 00000000 = 58a00000
00000001 << 00000001 = e9000000
00000002 << 00000002 = b5f40000
00000003 << 00000003 = 00000000
-- end output --
Comment 1 Richard Biener 2011-01-19 10:44:54 UTC
I can't see anything in the program that would be affected by a 'volatile'
keyword.  Instead I see a lot of bogus ways to try to circumvent type-based
aliasing rules (using volatile is one).  Use -fno-strict-aliasing.