Index: lib/Sema/SemaDeclCXX.cpp =================================================================== --- lib/Sema/SemaDeclCXX.cpp +++ lib/Sema/SemaDeclCXX.cpp @@ -4742,6 +4742,10 @@ if (MD && ClassExported) { if (MD->isUserProvided()) { + // Don't mark constexpr functions again + if (MD->isConstexpr()) + continue; + // Instantiate non-default methods.. // .. except for certain kinds of template specializations. Index: test/CodeGenCXX/dllexport.cpp =================================================================== --- test/CodeGenCXX/dllexport.cpp +++ test/CodeGenCXX/dllexport.cpp @@ -615,6 +615,10 @@ struct __declspec(dllexport) ExportedDerivedClass : NonExportedBaseClass {}; // M32-DAG: weak_odr dllexport x86_thiscallcc void @"\01??1ExportedDerivedClass@@UAE@XZ" +// Exported constexpr function is only codegened once. +template struct Q { constexpr Q() {} }; +template class __declspec(dllexport) Q; +// M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.Q* @"\01??0?$Q@X@@QAE@XZ"(%struct.Q* returned %this) //===----------------------------------------------------------------------===// // Classes with template base classes