Re: gcc 4.5.1 -fstrict-aliasing and store removal

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I now have a reduced test case.

Ian could you take a look and say whether this code looks OK to you?

--
Vyacheslav Egorov
#include <stdint.h>

#include <cstdio>
#include <cstring>
#include <cstdlib>

typedef uint8_t byte;
typedef byte* Address;

static const int kHeapObjectTag = 1;

class Object { };

class Context : public Object {
 public:
  static const int kSize = 40;
};

class GlobalObject : public Object {
 public:

#define FIELD_ADDR(obj, offset) \
  (reinterpret_cast<Address>(obj) - kHeapObjectTag + (offset))

#define WRITE_FIELD(obj, offset, value) \
  (*reinterpret_cast<Object**>(FIELD_ADDR(obj, offset)) = (value))

#define READ_FIELD(obj, offset) \
  (*reinterpret_cast<Object**>(FIELD_ADDR(obj, offset)))


  void set_global_context (Context* ctx) {
    WRITE_FIELD(this, kGlobalContextOffset, ctx);
  }

  Context* get_global_context () {
    return reinterpret_cast<Context*>(READ_FIELD(this, kGlobalContextOffset));
  }

  static const int kGlobalContextOffset = 32;
  static const int kSize = 2*kGlobalContextOffset;
};

template <class Dest, class Source>
inline Dest BitCast(const Source& source) {
  // Compile time assertion: sizeof(Dest) == sizeof(Source)
  // A compile error here means your Dest and Source have different sizes.
  typedef char VerifySizesAreEqual[sizeof(Dest) == sizeof(Source) ? 1 : -1];

  Dest dest;
  memcpy(&dest, &source, sizeof(dest));
  return dest;
}

template <class Dest, class Source>
inline Dest BitCast(Source* source) {
  return BitCast<Dest>(reinterpret_cast<uintptr_t>(source));
}

template<typename T>
class Handle {
 public:
  explicit Handle(T** location) : location_(location) {}

  T* operator -> () const {
    return operator*();
  }

  T* operator * () const {
    return *BitCast<T**>(location_);
  }

 private:
  T** location_;
};

__attribute__((noinline)) void set_global_context(Handle<GlobalObject> bar,
                                                  Handle<Context> ctx) {
  bar->set_global_context(*ctx);
}

template<typename T>
inline T* Allocate() {
  Address addr = (Address)malloc(T::kSize);
  return (T*) (addr + kHeapObjectTag);
}

int main(int argc, char* argv[]) {
  Context* global_context = Allocate<Context>();
  GlobalObject* global_object = Allocate<GlobalObject>();

  Handle<Context> h_global_context (&global_context);
  Handle<GlobalObject> h_global_object (&global_object);

  printf("global_context = %p, global_object->get_global_context() = %p\n",
         (void*)*h_global_context,
         (void*)h_global_object->get_global_context());

  set_global_context(h_global_object, h_global_context);

  printf("global_context = %p, global_object->get_global_context() = %p\n",
         (void*)*h_global_context,
         (void*)h_global_object->get_global_context());

  return 0;
}

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux