[cfe-dev] Runtime error with static template members

Talin viridia at gmail.com
Tue Apr 26 20:06:30 PDT 2011


Hi folks - I've decided to try building the Tart compiler using clang, and
I've managed to get everything to compile (whew!) but I'm getting a strange
runtime error which doesn't occur when I compile my code under gcc.

Let me explain what the code is doing. As you know, when you have a template
that has a static data member, the compiler generates a separate copy of
that data member for each instantiation of the template. I often use this
feature to generate static data structures from a set of template
parameters. In this particular case, I'm using it to construct function
signatures for the intrinsic (built-in) functions of my compiler.

The function signature includes an array of parameter definitions, each
having a type, a name, and so on. They are defined using a template that
looks like this:

/// -------------------------------------------------------------------
/// Template that generates a static formal parameter literal.
template<int type, int index, int paramFlags = 0>
class StaticParamDefn {
public:
  static ParameterDefn value;
};

template<int type, int index, int paramFlags>
ParameterDefn StaticParamDefn<type, index, paramFlags>::value(
  NULL,
  ParameterName<index>::value,
  &StaticType<type>::value, paramFlags);


This creates a static instance of the ParameterDefn structure. The
ParameterName<index>::value expression evaluates to a constant string such
as "a0", "a1", "a2" and so on. Similarly the &StaticType<type>::value
expression
evaluates to a pointer to a type object. The static type objects are defined
in a .cpp file, and they look like this:

template<> Type & StaticType<TypeId_Bool>::value = BoolType::instance;
template<> Type & StaticType<TypeId_Void>::value = VoidType::instance;
template<> Type & StaticType<TypeId_Char>::value = CharType::instance;
template<> Type & StaticType<TypeId_SInt8>::value = Int8Type::instance;
template<> Type & StaticType<TypeId_SInt16>::value = Int16Type::instance;
template<> Type & StaticType<TypeId_SInt32>::value = Int32Type::instance;
template<> Type & StaticType<TypeId_SInt64>::value = Int64Type::instance;
template<> Type & StaticType<TypeId_UInt8>::value = UInt8Type::instance;
template<> Type & StaticType<TypeId_UInt16>::value = UInt16Type::instance;
template<> Type & StaticType<TypeId_UInt32>::value = UInt32Type::instance;
template<> Type & StaticType<TypeId_UInt64>::value = UInt64Type::instance;
template<> Type & StaticType<TypeId_Float>::value = FloatType::instance;
template<> Type & StaticType<TypeId_Double>::value = DoubleType::instance;
template<> Type & StaticType<TypeId_UnsizedInt>::value =
UnsizedIntType::instance;


This template would normally be invoked like this:

&StaticParamDefn<TypeId_SInt32, 1, ParameterDefn::Variadic>::value,


OK, so now let me explain the problem I'm seeing. The ParameterDefn class
has an assert(type != NULL) in its constructor, to insure that the type
argument is non-NULL. It's this assertion that is failing under clang but
not under gcc. I should note that the name parameter is fine, it's only the
type parameter that is problematic.

I suspect that the problem is related to the order in which static
constructors are being invoked. I'm guessing that the "Type &" variables are
actually pointers, and the values are being initialized after the
ParameterDefn constructor runs. I had always assumed that the Type &
pointers were filled in at compile time, since I never had a problem with
this before.

My question is - is there any way to make this work under clang?

-- 
-- Talin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20110426/d5a52435/attachment.html>


More information about the cfe-dev mailing list