[clang][Interp] Fix visiting non-FieldDecl MemberExprs

Ignore the base and visit the Member decl like a regular DeclRefExpr.
This commit is contained in:
Timm Bäder
2024-06-11 18:12:37 +02:00
parent 00c5474918
commit 4cf607fa15
2 changed files with 14 additions and 13 deletions

View File

@@ -1494,6 +1494,9 @@ bool ByteCodeExprGen<Emitter>::VisitMemberExpr(const MemberExpr *E) {
return false;
}
if (!isa<FieldDecl>(Member))
return this->discard(Base) && this->visitDeclRef(Member, E);
if (Initializing) {
if (!this->delegate(Base))
return false;
@@ -1503,19 +1506,16 @@ bool ByteCodeExprGen<Emitter>::VisitMemberExpr(const MemberExpr *E) {
}
// Base above gives us a pointer on the stack.
if (const auto *FD = dyn_cast<FieldDecl>(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<FieldDecl>(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 <class Emitter>

View File

@@ -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 };