diff --git a/clang/lib/AST/Interp/Interp.cpp b/clang/lib/AST/Interp/Interp.cpp index 1b9f3cfd3a167..0ce64a572c263 100644 --- a/clang/lib/AST/Interp/Interp.cpp +++ b/clang/lib/AST/Interp/Interp.cpp @@ -485,7 +485,9 @@ bool CheckCallable(InterpState &S, CodePtr OpPC, const Function *F) { // Don't emit anything if the function isn't defined and we're checking // for a constant expression. It might be defined at the point we're // actually calling it. - if (!DiagDecl->isDefined() && S.checkingPotentialConstantExpression()) + bool IsExtern = DiagDecl->getStorageClass() == SC_Extern; + if (!DiagDecl->isDefined() && !IsExtern && + S.checkingPotentialConstantExpression()) return false; // If the declaration is defined _and_ declared 'constexpr', the below diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp index 7ddc56c9b5dfc..769e48fe478a5 100644 --- a/clang/test/AST/Interp/records.cpp +++ b/clang/test/AST/Interp/records.cpp @@ -1238,3 +1238,9 @@ namespace InvalidCtorInitializer { // no crash on evaluating the constexpr ctor. constexpr int Z = X().Y; // both-error {{constexpr variable 'Z' must be initialized by a constant expression}} } + +extern int f(); // both-note {{here}} +struct HasNonConstExprMemInit { + int x = f(); // both-note {{non-constexpr function}} + constexpr HasNonConstExprMemInit() {} // both-error {{never produces a constant expression}} +};