diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 0385ca4b3a06..820e4cc44a7b 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1494,6 +1494,9 @@ bool ByteCodeExprGen::VisitMemberExpr(const MemberExpr *E) { return false; } + if (!isa(Member)) + return this->discard(Base) && this->visitDeclRef(Member, E); + if (Initializing) { if (!this->delegate(Base)) return false; @@ -1503,19 +1506,16 @@ bool ByteCodeExprGen::VisitMemberExpr(const MemberExpr *E) { } // Base above gives us a pointer on the stack. - if (const auto *FD = dyn_cast(Member)) { - const RecordDecl *RD = FD->getParent(); - const Record *R = getRecord(RD); - if (!R) - return false; - const Record::Field *F = R->getField(FD); - // Leave a pointer to the field on the stack. - if (F->Decl->getType()->isReferenceType()) - return this->emitGetFieldPop(PT_Ptr, F->Offset, E) && maybeLoadValue(); - return this->emitGetPtrFieldPop(F->Offset, E) && maybeLoadValue(); - } - - return false; + const auto *FD = cast(Member); + const RecordDecl *RD = FD->getParent(); + const Record *R = getRecord(RD); + if (!R) + return false; + const Record::Field *F = R->getField(FD); + // Leave a pointer to the field on the stack. + if (F->Decl->getType()->isReferenceType()) + return this->emitGetFieldPop(PT_Ptr, F->Offset, E) && maybeLoadValue(); + return this->emitGetPtrFieldPop(F->Offset, E) && maybeLoadValue(); } template diff --git a/clang/test/SemaCXX/ms-const-member-expr.cpp b/clang/test/SemaCXX/ms-const-member-expr.cpp index 72cfe76fbe43..8312f84b550f 100644 --- a/clang/test/SemaCXX/ms-const-member-expr.cpp +++ b/clang/test/SemaCXX/ms-const-member-expr.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -std=c++11 -fms-compatibility -fsyntax-only -verify +// RUN: %clang_cc1 %s -std=c++11 -fms-compatibility -fsyntax-only -verify -fexperimental-new-constant-interpreter struct S { enum { E = 1 };