tbaeder updated this revision to Diff 453610.
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
@@ -32,3 +32,12 @@
static_assert(!0, "");
static_assert(-true, "");
static_assert(-false, ""); //expected-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;
+}
Index: clang/test/AST/Interp/cxx20.cpp
===================================================================
--- /dev/null
+++ clang/test/AST/Interp/cxx20.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++20 -verify %s
+// RUN: %clang_cc1 -std=c++20 -verify %s -DREFERENCE
+
+
+// expected-no-diagnostics
+constexpr int getMinus5() {
+ int a = 10;
+ a = -5;
+ int *p = &a;
+ return *p;
+}
+
+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
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
@@ -103,6 +103,7 @@
if (!this->emitLoadPop(T, CE))
return false;
return DiscardResult ? this->emitPop(T, CE) : true;
+ return true;
});
}
@@ -209,6 +210,12 @@
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;
+ // TODO: Assignments return the assigned value, so the pop() here
+ // should proably just go away.
+ return this->emitPopPtr(BO);
default:
return this->bail(BO);
}
@@ -596,8 +603,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++
@@ -607,16 +613,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
@@ -628,6 +650,24 @@
return false;
}
+template <class Emitter>
+bool ByteCodeExprGen<Emitter>::VisitDeclRefExpr(const DeclRefExpr *E) {
+ if (auto It = Locals.find(E->getDecl()); It != Locals.end()) {
+ const unsigned Offset = It->second.Offset;
+ return this->emitGetPtrLocal(Offset, E);
+ } else if (auto GlobalIndex = P.getGlobal(E->getDecl())) {
+ return this->emitGetPtrGlobal(*GlobalIndex, E);
+ } else if (isa<ParmVarDecl>(E->getDecl())) {
+ // I'm pretty sure we should do something here, BUT
+ // when we're in evaluateAsRValue(), we don't have any parameters,
+ // so we can't actually use this->Params. This happens when
+ // a parameter is used in a return statement.
+ return false;
+ }
+
+ return false;
+}
+
template <class Emitter>
void ByteCodeExprGen<Emitter>::emitCleanup() {
for (VariableScope<Emitter> *C = VarScope; C; C = C->getParent())
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits