A trivial test case requires guard variable but it need not

Hi,

I am not sure which of the recent patches related to recent c++11 initializer work caused this.
In this trivial test case, clang now generates a guard variable. It need not. This breaks several
of our projects which do not need (must not have) guard variable.

class IOService;

struct IOSurfaceSendRight { void foo(); };

typedef int (IOService::*IOMethod)();

void a() {
  static IOMethod x = (IOMethod)&IOSurfaceSendRight::foo;
}

% clang -c test.cpp

% nm -nm test.o | grep guard
                 (undefined) external ___cxa_guard_acquire
                 (undefined) external ___cxa_guard_release

% nm -nm test.o | grep guard
                 (undefined) external ___cxa_guard_acquire
                 (undefined) external ___cxa_guard_release

We lost this in a ‘cleanup’ change quite a while back, which removed the clang::Expr → llvm::Constant emission of member pointers, under the theory that the clang::APValue → llvm::Constant emission covered all use cases. It appears that reinterpret_casts of pointers to members were covered by the old code but not the new code :frowning:

It should hopefully be straightforward to extend the constant expression evaluator to deal with such reinterpret_casts.

  • Richard