This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: middle-end/9725: Invalid dependency determination
- From: "Jan Beulich" <JBeulich at novell dot com>
- To: <bangerth at dealii dot org>,<velco at fadata dot bg>
- Cc: <gcc-bugs at gcc dot gnu dot org>,<gcc-prs at gcc dot gnu dot org>, <nobody at gcc dot gnu dot org>
- Date: Wed, 19 Feb 2003 16:38:40 +0100
- Subject: Re: middle-end/9725: Invalid dependency determination
I'm sorry, but I have to continue on this, hoping to fully understand
this. When starting to convert the problematic definitions to something
that would meet the standard's needs, I found further unexplainable (to
me) behavior. When setting up a union that aliases a builtin type and a
structure (to access pieces of the built in type - gcc sources do so,
too: see the FLO_union_type in config/fp-bit.h) then depending on how I
use this the compiler may or may not honor the alias. Reading the
aggregate respective clause of the standard excerpt I'm getting mixed
feelings here:
On one hand, the original type (top-level for that expression) used is
a union meeing the criteria.
On the other hand, the sub-expression referencing the structure has the
type of the structure, hence the access may be viewed as happening
through that structure, which does not meet the criteria.
The real odd thing is that the compiler, for the following example,
#define FULL long long
#define HALF int
#define QUARTER short
struct s {
unsigned HALF h;
unsigned QUARTER q;
};
union u {
unsigned FULL f;
struct s s;
};
void test2(unsigned FULL*pf, unsigned HALF h, unsigned QUARTER q) {
unsigned FULL f;
((union u*)&f)->s.h = h;
((union u*)&f)->s.q = q;
*pf = f;
}
void test3(unsigned FULL*pf, unsigned HALF h, unsigned QUARTER q) {
unsigned FULL f;
(&((union u*)&f)->s)->h = h;
(&((union u*)&f)->s)->q = q;
*pf = f;
}
void test4(unsigned FULL*pf, unsigned HALF h, unsigned QUARTER q) {
unsigned FULL f;
(*&((union u*)&f)->s).h = h;
(*&((union u*)&f)->s).q = q;
*pf = f;
}
honors the aliasing only in test2(), but not in test3() and test4().
While I may view this as an indication that in case of test2(), the
compiler simply doesn't employ the aliasing information it has, this
presents several problems:
- footnote 79 (applying to section 6.5.3.2, paragraph 4) does not hold
- there would be no way to access in pieces a built-in type (a rather
common operation in all sorts of sources I came to see)
- gcc sources (as pointed out at the top) themselves employ this
feature and would thus not be guaranteed to compile correctly with their
own compiler
Looking forward to clarification of all of this; hopefully it just
again so that I'm not seeing the full picture...
Thank you very much, Jan
>>> Momchil Velikov <velco at fadata dot bg> 17.02.03 17:52:05 >>>
>>>>> "Jan" == Jan Beulich <JBeulich at novell dot com> writes:
Jan> I was fearing you would say this. But I can in no way agree -
the code
Jan> presented is valid C, and hence should work at any
optimization level.
It is not valid C because it violates the following exceprt from the
ISO/IEC 9899:1999:
[#7] An object shall have its stored value accessed only by
an lvalue expression that has one of the following types:73)
-- a type compatible with the effective type of the
object,
-- a qualified version of a type compatible with the
effective type of the object,
-- a type that is the signed or unsigned type
corresponding to the effective type of the object,
-- a type that is the signed or unsigned type
corresponding to a qualified version of the effective
type of the object,
-- an aggregate or union type that includes one of the
aforementioned types among its members (including,
recursively, a member of a subaggregate or contained
union), or
-- a character type.
~velco