https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61556
Bug ID: 61556 Summary: [c++11][regression] ‘*(const ValueType*)this’ is not a constant expression with valid code Product: gcc Version: 4.9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: l.jirkovsky at gmail dot com When used in a certain way, a template class cannot be instantiated in another template class using a static constexpr. I tracked the regression down to the following commit: commit 18619da58c77461642c36cee9f0463c968877f75 Author: jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Mon Apr 1 19:05:12 2013 +0000 * call.c (add_function_candidate): Take the address of 'this' here. (build_over_call): And here. (build_new_method_call_1, build_op_call_1): Not here. (build_user_type_conversion_1): Or here. (add_candidates): Adjust. Reverting this commit fixes the problem on the current gcc. The problematic code that should be compilable is attached after the "CODE" section. When compiled with gcc 4.9.0, the ValueTypeInfo<ValueTypeEnum::doubleval> v; in the FillFunctor constructor gives an error: bug2.cpp: In constructor ‘FillFunctor<Format>::FillFunctor()’: bug2.cpp:24:41: in constexpr expansion of ‘const ValueType{1}->ValueType::operator int()’ bug2.cpp:24:41: error: ‘*(const ValueType*)this’ is not a constant expression ValueTypeInfo<ValueTypeEnum::doubleval> v; ^ bug2.cpp:24:41: note: in template argument for type ‘int’ bug2.cpp:24:44: error: invalid type in declaration before ‘;’ token ValueTypeInfo<ValueTypeEnum::doubleval> v; However, the same expression compiles just fine if its used in a function, such as main(). Removing m_ID makes the code compile, too. Also, the compilation works after replacing: ValueTypeInfo<ValueTypeEnum::doubleval> v; with a: constexpr ValueType doubleval = ValueType(1); ValueTypeInfo<doubleval> v; CODE ##### class ValueType { public: constexpr operator int() const {return m_ID;}; constexpr ValueType(const int v) : m_ID(v) {} private: int m_ID; }; class ValueTypeEnum { public: static constexpr ValueType doubleval = ValueType(1); }; template <int format> class ValueTypeInfo { }; template <typename Format> class FillFunctor { public: FillFunctor() { ValueTypeInfo<ValueTypeEnum::doubleval> v; } }; int main() { ValueTypeInfo<ValueTypeEnum::doubleval> v; }