diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 81a5296012b9aa..77a1c64d40189c 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -3948,9 +3948,17 @@ bool ByteCodeExprGen::visitDeclRef(const ValueDecl *D, const Expr *E) { // we haven't seen yet. if (Ctx.getLangOpts().CPlusPlus) { if (const auto *VD = dyn_cast(D)) { + const auto typeShouldBeVisited = [&](QualType T) -> bool { + if (T.isConstant(Ctx.getASTContext())) + return true; + if (const auto *RT = T->getAs()) + return RT->getPointeeType().isConstQualified(); + return false; + }; + // Visit local const variables like normal. if ((VD->isLocalVarDecl() || VD->isStaticDataMember()) && - VD->getType().isConstant(Ctx.getASTContext())) { + typeShouldBeVisited(VD->getType())) { if (!this->visitVarDecl(VD)) return false; // Retry. diff --git a/clang/test/AST/Interp/cxx11.cpp b/clang/test/AST/Interp/cxx11.cpp index f06a5dd173cbaa..82b2727bbadbb1 100644 --- a/clang/test/AST/Interp/cxx11.cpp +++ b/clang/test/AST/Interp/cxx11.cpp @@ -46,3 +46,19 @@ constexpr int preInc(int x) { // both-error {{never produces a constant expressi constexpr int postInc(int x) { // both-error {{never produces a constant expression}} return x++; // both-note {{subexpression}} } + + +namespace ReferenceToConst { + template struct S; // both-note 1{{here}} + struct LiteralType { + constexpr LiteralType(int n) : n(n) {} + int n; + }; + template struct T { + T() { + static const int ki = 42; + const int &i2 = ki; + typename S::T check5; // both-error {{undefined template}} + } + }; +}