new warnings

In file included from DeclGroup.cpp:14:
/Volumes/mrs5/net/llvm/llvm/tools/clang/lib/AST/../../include/clang/AST/DeclGroup.h: In member function ‘clang::Decl** clang::DeclGroupRef::begin()’:
/Volumes/mrs5/net/llvm/llvm/tools/clang/lib/AST/../../include/clang/AST/DeclGroup.h:65: warning: dereferencing type-punned pointer will break strict-aliasing rules
/Volumes/mrs5/net/llvm/llvm/tools/clang/lib/AST/../../include/clang/AST/DeclGroup.h: In member function ‘clang::Decl** clang::DeclGroupRef::end()’:
/Volumes/mrs5/net/llvm/llvm/tools/clang/lib/AST/../../include/clang/AST/DeclGroup.h:73: warning: dereferencing type-punned pointer will break strict-aliasing rules

Thanks Mike,

Any suggestion on how to fix this? We're basically using the field as a variant, this it is perfectly safe (I believe).

Ted

class DeclGroupRef {
   uintptr_t ThePtr;

   iterator begin() {
     if (getKind() == DeclKind)
       return ThePtr ? (Decl**) &ThePtr : 0;

? You think that is safe? Why? I don't see any unions, I don't see any memcpys, no character types.

Let me put is plainly, you can't access a type as another type and expect it to work. There are a couple exceptions to this, and if you want to make use of them, you have to know which one it is and meet the requirements for it. Which exception were you trying to make use of:

        [#7] An object shall have its stored value accessed only by
        an lvalue expression that has one of the following types:61)

          -- 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.

? [ toquote the the C rules, as my fingers for some reason didn't find the C++ rules in seconds ]

If you want to do math on a pointer, convert to uintptr_t and then do the math, that's safe.

* Mike Stump:

? [ toquote the the C rules, as my fingers for some reason didn't
find the C++ rules in seconds ]

The C++ rules are different. I think the warning is bogus in C++ mode.
[basic.lval] rules out most of the strict aliasing analysis, AFAIK.

Florian Weimer wrote:

* Mike Stump:

? [ toquote the the C rules, as my fingers for some reason didn't find the C++ rules in seconds ]
    
The C++ rules are different. I think the warning is bogus in C++ mode.
[basic.lval] rules out most of the strict aliasing analysis, AFAIK.
  

Here's the 3.10/15, which discusses aliasing:

If a program attempts to access the stored value of an object through an lvalue of other than one of the fol-
lowing types the behavior is undefined48):
— the dynamic type of the object,
— a cv-qualified version of the dynamic type of the object,
— a type that is the signed or unsigned type corresponding to the dynamic type of the object,
— a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of
    the object,
— an aggregate or union type that includes one of the aforementioned types among its members (includ-
    ing, recursively, a member of a subaggregate or contained union),
— a type that is a (possibly cv-qualified) base class type of the dynamic type of the object,
— a char or unsigned char type.

48) The intent of this list is to specify those circumstances in which an object may or may not be aliased.

That's a reinterpret_cast, so my understanding is that it's legal iff
ThePtr was originally set by a reinterpret_cast from something with
static type Decl**.

You're focusing in on the wrong thing. For what you're focused on, yes, that part is fine. Instead, ask yourself, does he ever fetch an object that has a different type then the type of the stored object? If yes, does it fall within the rules for C++ aliasing? See my other email for more details of what is wrong with the current version.