diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index d81496ffd74e0..e5ca6912ed566 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -2407,8 +2407,11 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, return false; // A dllimport variable never acts like a constant, unless we're - // evaluating a value for use only in name mangling. - if (!isForManglingOnly(Kind) && Var->hasAttr()) + // evaluating a value for use only in name mangling, and unless we're a + // static local. For the latter case, we'd still need to evaluate the + // constant expression in case we're inside a (inlined) function. + if (!isForManglingOnly(Kind) && Var->hasAttr() && + !Var->isStaticLocal()) // FIXME: Diagnostic! return false; diff --git a/clang/test/SemaCXX/dllimport.cpp b/clang/test/SemaCXX/dllimport.cpp index b7a1a62b8725b..eaf217c8e2d3b 100644 --- a/clang/test/SemaCXX/dllimport.cpp +++ b/clang/test/SemaCXX/dllimport.cpp @@ -1526,6 +1526,40 @@ template struct __declspec(dllimport) PartiallySpecializedClassTemp template struct ExpliciallySpecializedClassTemplate {}; template <> struct __declspec(dllimport) ExpliciallySpecializedClassTemplate { void f() {} }; +// Function-local static constexpr in dllimport function (or class). +struct DLLImportFuncWithConstexprStatic { +#if defined(GNU) +// expected-warning@+2{{'dllimport' attribute ignored on inline function}} +#endif + __declspec(dllimport) static const int *func() { + static constexpr int value = 42; + static constexpr const int *p = &value; + static_assert(*p == 42, ""); + return p; + } +}; +const int* (*pFunc)() = &DLLImportFuncWithConstexprStatic::func; +bool UsedDLLImportFuncWithConstexprStatic() { + return pFunc() == DLLImportFuncWithConstexprStatic::func(); +} + +#if !defined(PS) +struct DLLImportInlineFuncWithConstexprStatic { +#if defined(GNU) + // expected-warning@+2{{'dllimport' attribute ignored on inline function}} +#endif + __declspec(dllimport) __forceinline static const int* funcForceInline() { + static constexpr int value = 42; + static constexpr const int* p = &value; + static_assert(*p == 42, ""); + return p; + } +}; +const int* (*pFuncForceInline)() = &DLLImportInlineFuncWithConstexprStatic::funcForceInline; +bool UsedDLLImportInlineFuncWithConstexprStatic() { + return pFuncForceInline() == DLLImportInlineFuncWithConstexprStatic::funcForceInline(); +} +#endif // !PS //===----------------------------------------------------------------------===// // Classes with template base classes