tbaeder updated this revision to Diff 454164.

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

https://reviews.llvm.org/D132111

Files:
  clang/lib/AST/Interp/ByteCodeExprGen.cpp
  clang/lib/AST/Interp/ByteCodeExprGen.h
  clang/test/AST/Interp/cxx20.cpp
  clang/test/AST/Interp/literals.cpp

Index: clang/test/AST/Interp/literals.cpp
===================================================================
--- clang/test/AST/Interp/literals.cpp
+++ clang/test/AST/Interp/literals.cpp
@@ -31,3 +31,19 @@
 static_assert(!0, "");
 static_assert(-true, "");
 static_assert(-false, ""); //expected-error{{failed}} ref-error{{failed}}
+
+constexpr int m = 10;
+constexpr const int *p = &m;
+static_assert(p != nullptr, "");
+static_assert(*p == 10, "");
+
+constexpr const int* getIntPointer() {
+  return &m;
+}
+//static_assert(getIntPointer() == &m, ""); TODO
+//static_assert(*getIntPointer() == 10, ""); TODO
+
+constexpr int gimme(int k) {
+  return k;
+}
+// static_assert(gimme(5) == 5, ""); TODO
Index: clang/test/AST/Interp/cxx20.cpp
===================================================================
--- /dev/null
+++ clang/test/AST/Interp/cxx20.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++20 -verify %s
+// RUN: %clang_cc1 -std=c++20 -verify=ref %s
+
+
+// expected-no-diagnostics
+constexpr int getMinus5() {
+  int a = 10;
+  a = -5;
+  int *p = &a;
+  return *p;
+}
+//static_assert(getMinus5() == -5, "") TODO
+
+constexpr int assign() {
+  int m = 10;
+  int k = 12;
+
+  m = (k = 20);
+
+  return m;
+}
+//static_assert(assign() == 20, "");  TODO
+
+
+constexpr int pointerAssign() {
+  int m = 10;
+  int *p = &m;
+
+  *p = 12; // modifies m
+
+  return m;
+}
+//static_assert(pointerAssign() == 12, "");  TODO
+
+constexpr int pointerDeref() {
+  int m = 12;
+  int *p = &m;
+
+  return *p;
+}
+//static_assert(pointerDeref() == 12, ""); TODO
+
+constexpr int pointerAssign2() {
+  int m = 10;
+  int *p = &m;
+  int **pp = &p;
+
+  **pp = 12;
+
+  int v = **pp;
+
+  return v;
+}
+//static_assert(pointerAssign2() == 12, ""); TODO
Index: clang/lib/AST/Interp/ByteCodeExprGen.h
===================================================================
--- clang/lib/AST/Interp/ByteCodeExprGen.h
+++ clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -72,6 +72,7 @@
   bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E);
   bool VisitCXXNullPtrLiteralExpr(const CXXNullPtrLiteralExpr *E);
   bool VisitUnaryOperator(const UnaryOperator *E);
+  bool VisitDeclRefExpr(const DeclRefExpr *E);
 
 protected:
   bool visitExpr(const Expr *E) override;
Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp
===================================================================
--- clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -221,6 +221,10 @@
       return Discard(this->emitAdd(*T, BO));
     case BO_Mul:
       return Discard(this->emitMul(*T, BO));
+    case BO_Assign:
+      if (!this->emitStore(*T, BO))
+        return false;
+      return DiscardResult ? this->emitPopPtr(BO) : true;
     default:
       return this->bail(BO);
     }
@@ -608,8 +612,7 @@
 
 template <class Emitter>
 bool ByteCodeExprGen<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
-  if (!this->Visit(E->getSubExpr()))
-    return false;
+  const Expr *SubExpr = E->getSubExpr();
 
   switch (E->getOpcode()) {
   case UO_PostInc: // x++
@@ -619,16 +622,32 @@
     return false;
 
   case UO_LNot: // !x
+    if (!this->Visit(SubExpr))
+      return false;
     return this->emitInvBool(E);
   case UO_Minus: // -x
+    if (!this->Visit(SubExpr))
+      return false;
     if (Optional<PrimType> T = classify(E->getType()))
       return this->emitNeg(*T, E);
     return false;
   case UO_Plus:  // +x
-    return true; // noop
+    return this->Visit(SubExpr); // noop
 
   case UO_AddrOf: // &x
+    // We should already have a pointer when we get here.
+    return this->Visit(SubExpr);
+
   case UO_Deref:  // *x
+    return dereference(
+        SubExpr, DerefKind::Read,
+        [](PrimType) {
+          llvm_unreachable("Dereferencing requires a pointer");
+          return false;
+        },
+        [this, E](PrimType T) {
+          return DiscardResult ? this->emitPop(T, E) : true;
+        });
   case UO_Not:    // ~x
   case UO_Real:   // __real x
   case UO_Imag:   // __imag x
@@ -640,6 +659,23 @@
   return false;
 }
 
+template <class Emitter>
+bool ByteCodeExprGen<Emitter>::VisitDeclRefExpr(const DeclRefExpr *E) {
+  const auto *Decl = E->getDecl();
+
+  if (auto It = Locals.find(Decl); It != Locals.end()) {
+    const unsigned Offset = It->second.Offset;
+    return this->emitGetPtrLocal(Offset, E);
+  } else if (auto GlobalIndex = P.getGlobal(Decl)) {
+    return this->emitGetPtrGlobal(*GlobalIndex, E);
+  } else if (const auto *PVD = dyn_cast<ParmVarDecl>(Decl)) {
+    if (auto It = this->Params.find(PVD); It != this->Params.end())
+      return this->emitGetPtrParam(It->second, E);
+  }
+
+  return false;
+}
+
 template <class Emitter>
 void ByteCodeExprGen<Emitter>::emitCleanup() {
   for (VariableScope<Emitter> *C = VarScope; C; C = C->getParent())
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to