This revision was automatically updated to reflect the committed changes.
tbaeder marked an inline comment as done.
Closed by commit rG0ccff030f3b4: [clang][Interp] Fix record members of 
reference type (authored by tbaeder).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D136012/new/

https://reviews.llvm.org/D136012

Files:
  clang/lib/AST/Interp/ByteCodeExprGen.cpp
  clang/lib/AST/Interp/ByteCodeStmtGen.cpp
  clang/lib/AST/Interp/Interp.h
  clang/test/AST/Interp/references.cpp


Index: clang/test/AST/Interp/references.cpp
===================================================================
--- clang/test/AST/Interp/references.cpp
+++ clang/test/AST/Interp/references.cpp
@@ -88,3 +88,29 @@
   return j;
 }
 static_assert(RefToMemberExpr() == 11, "");
+
+struct Ref {
+  int &a;
+};
+
+constexpr int RecordWithRef() {
+  int m = 100;
+  Ref r{m};
+  m = 200;
+  return r.a;
+}
+static_assert(RecordWithRef() == 200, "");
+
+
+struct Ref2 {
+  int &a;
+  constexpr Ref2(int &a) : a(a) {}
+};
+
+constexpr int RecordWithRef2() {
+  int m = 100;
+  Ref2 r(m);
+  m = 200;
+  return r.a;
+}
+static_assert(RecordWithRef2() == 200, "");
Index: clang/lib/AST/Interp/Interp.h
===================================================================
--- clang/lib/AST/Interp/Interp.h
+++ clang/lib/AST/Interp/Interp.h
@@ -470,6 +470,8 @@
   return true;
 }
 
+/// 1) Peeks a pointer on the stack
+/// 2) Pushes the value of the pointer's field on the stack
 template <PrimType Name, class T = typename PrimConv<Name>::T>
 bool GetField(InterpState &S, CodePtr OpPC, uint32_t I) {
   const Pointer &Obj = S.Stk.peek<Pointer>();
@@ -499,6 +501,8 @@
   return true;
 }
 
+/// 1) Pops a pointer from the stack
+/// 2) Pushes the value of the pointer's field on the stack
 template <PrimType Name, class T = typename PrimConv<Name>::T>
 bool GetFieldPop(InterpState &S, CodePtr OpPC, uint32_t I) {
   const Pointer &Obj = S.Stk.pop<Pointer>();
Index: clang/lib/AST/Interp/ByteCodeStmtGen.cpp
===================================================================
--- clang/lib/AST/Interp/ByteCodeStmtGen.cpp
+++ clang/lib/AST/Interp/ByteCodeStmtGen.cpp
@@ -105,7 +105,7 @@
       if (const FieldDecl *Member = Init->getMember()) {
         const Record::Field *F = R->getField(Member);
 
-        if (Optional<PrimType> T = this->classify(InitExpr->getType())) {
+        if (Optional<PrimType> T = this->classify(InitExpr)) {
           if (!this->emitThis(InitExpr))
             return false;
 
Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp
===================================================================
--- clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -343,6 +343,8 @@
     const Record *R = getRecord(RD);
     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);
     return this->emitGetPtrField(F->Offset, E);
   }
 
@@ -809,7 +811,7 @@
       if (!this->emitDupPtr(Initializer))
         return false;
 
-      if (Optional<PrimType> T = classify(Init->getType())) {
+      if (Optional<PrimType> T = classify(Init)) {
         if (!this->visit(Init))
           return false;
 


Index: clang/test/AST/Interp/references.cpp
===================================================================
--- clang/test/AST/Interp/references.cpp
+++ clang/test/AST/Interp/references.cpp
@@ -88,3 +88,29 @@
   return j;
 }
 static_assert(RefToMemberExpr() == 11, "");
+
+struct Ref {
+  int &a;
+};
+
+constexpr int RecordWithRef() {
+  int m = 100;
+  Ref r{m};
+  m = 200;
+  return r.a;
+}
+static_assert(RecordWithRef() == 200, "");
+
+
+struct Ref2 {
+  int &a;
+  constexpr Ref2(int &a) : a(a) {}
+};
+
+constexpr int RecordWithRef2() {
+  int m = 100;
+  Ref2 r(m);
+  m = 200;
+  return r.a;
+}
+static_assert(RecordWithRef2() == 200, "");
Index: clang/lib/AST/Interp/Interp.h
===================================================================
--- clang/lib/AST/Interp/Interp.h
+++ clang/lib/AST/Interp/Interp.h
@@ -470,6 +470,8 @@
   return true;
 }
 
+/// 1) Peeks a pointer on the stack
+/// 2) Pushes the value of the pointer's field on the stack
 template <PrimType Name, class T = typename PrimConv<Name>::T>
 bool GetField(InterpState &S, CodePtr OpPC, uint32_t I) {
   const Pointer &Obj = S.Stk.peek<Pointer>();
@@ -499,6 +501,8 @@
   return true;
 }
 
+/// 1) Pops a pointer from the stack
+/// 2) Pushes the value of the pointer's field on the stack
 template <PrimType Name, class T = typename PrimConv<Name>::T>
 bool GetFieldPop(InterpState &S, CodePtr OpPC, uint32_t I) {
   const Pointer &Obj = S.Stk.pop<Pointer>();
Index: clang/lib/AST/Interp/ByteCodeStmtGen.cpp
===================================================================
--- clang/lib/AST/Interp/ByteCodeStmtGen.cpp
+++ clang/lib/AST/Interp/ByteCodeStmtGen.cpp
@@ -105,7 +105,7 @@
       if (const FieldDecl *Member = Init->getMember()) {
         const Record::Field *F = R->getField(Member);
 
-        if (Optional<PrimType> T = this->classify(InitExpr->getType())) {
+        if (Optional<PrimType> T = this->classify(InitExpr)) {
           if (!this->emitThis(InitExpr))
             return false;
 
Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp
===================================================================
--- clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -343,6 +343,8 @@
     const Record *R = getRecord(RD);
     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);
     return this->emitGetPtrField(F->Offset, E);
   }
 
@@ -809,7 +811,7 @@
       if (!this->emitDupPtr(Initializer))
         return false;
 
-      if (Optional<PrimType> T = classify(Init->getType())) {
+      if (Optional<PrimType> T = classify(Init)) {
         if (!this->visit(Init))
           return false;
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to