[clang] 77aaf46 - [clang][Interp] Implement ConditionalOperators
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 14 04:28:45 PDT 2022
Author: Timm Bäder
Date: 2022-10-14T13:16:10+02:00
New Revision: 77aaf469a7ae5af26a8fe92ed9d548404831d3ed
URL: https://github.com/llvm/llvm-project/commit/77aaf469a7ae5af26a8fe92ed9d548404831d3ed
DIFF: https://github.com/llvm/llvm-project/commit/77aaf469a7ae5af26a8fe92ed9d548404831d3ed.diff
LOG: [clang][Interp] Implement ConditionalOperators
Differential Revision: https://reviews.llvm.org/D134801
Added:
Modified:
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/ByteCodeExprGen.h
clang/test/AST/Interp/literals.cpp
clang/test/SemaCXX/constexpr-factorial.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 107fd77c974d6..2a25380df6072 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -347,6 +347,37 @@ bool ByteCodeExprGen<Emitter>::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
return this->visit(E->getSourceExpr());
}
+template <class Emitter>
+bool ByteCodeExprGen<Emitter>::VisitAbstractConditionalOperator(
+ const AbstractConditionalOperator *E) {
+ const Expr *Condition = E->getCond();
+ const Expr *TrueExpr = E->getTrueExpr();
+ const Expr *FalseExpr = E->getFalseExpr();
+
+ LabelTy LabelEnd = this->getLabel(); // Label after the operator.
+ LabelTy LabelFalse = this->getLabel(); // Label for the false expr.
+
+ if (!this->visit(Condition))
+ return false;
+ if (!this->jumpFalse(LabelFalse))
+ return false;
+
+ if (!this->visit(TrueExpr))
+ return false;
+ if (!this->jump(LabelEnd))
+ return false;
+
+ this->emitLabel(LabelFalse);
+
+ if (!this->visit(FalseExpr))
+ return false;
+
+ this->fallthrough(LabelEnd);
+ this->emitLabel(LabelEnd);
+
+ return true;
+}
+
template <class Emitter> bool ByteCodeExprGen<Emitter>::discard(const Expr *E) {
OptionScope<Emitter> Scope(this, /*NewDiscardResult=*/true);
return this->Visit(E);
diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.h b/clang/lib/AST/Interp/ByteCodeExprGen.h
index 32ff72aa36fb8..5e5bbbd6948aa 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.h
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -88,6 +88,7 @@ class ByteCodeExprGen : public ConstStmtVisitor<ByteCodeExprGen<Emitter>, bool>,
bool VisitMemberExpr(const MemberExpr *E);
bool VisitArrayInitIndexExpr(const ArrayInitIndexExpr *E);
bool VisitOpaqueValueExpr(const OpaqueValueExpr *E);
+ bool VisitAbstractConditionalOperator(const AbstractConditionalOperator *E);
protected:
bool visitExpr(const Expr *E) override;
diff --git a/clang/test/AST/Interp/literals.cpp b/clang/test/AST/Interp/literals.cpp
index cc868266e4a28..f11107c0efb76 100644
--- a/clang/test/AST/Interp/literals.cpp
+++ b/clang/test/AST/Interp/literals.cpp
@@ -210,3 +210,54 @@ namespace div {
// expected-note {{value 2147483648 is outside the range}} \
};
+
+namespace cond {
+ constexpr bool isEven(int n) {
+ return n % 2 == 0 ? true : false;
+ }
+ static_assert(isEven(2), "");
+ static_assert(!isEven(3), "");
+ static_assert(isEven(100), "");
+
+ constexpr int M = 5 ? 10 : 20;
+ static_assert(M == 10, "");
+
+ static_assert(5 ? 13 : 16 == 13, "");
+ static_assert(0 ? 13 : 16 == 16, "");
+
+ static_assert(number ?: -15 == number, "");
+ static_assert(0 ?: 100 == 100 , "");
+
+#if __cplusplus >= 201402L
+ constexpr int N = 20;
+ constexpr int foo() {
+ int m = N > 0 ? 5 : 10;
+
+ return m == 5 ? isEven(m) : true;
+ }
+ static_assert(foo() == false, "");
+
+ constexpr int dontCallMe(unsigned m) {
+ if (m == 0) return 0;
+ return dontCallMe(m - 2);
+ }
+
+ // Can't call this because it will run into infinite recursion.
+ constexpr int assertNotReached() {
+ return dontCallMe(3);
+ }
+
+ constexpr int testCond() {
+ return true ? 5 : assertNotReached();
+ }
+
+ constexpr int testCond2() {
+ return false ? assertNotReached() : 10;
+ }
+
+ static_assert(testCond() == 5, "");
+ static_assert(testCond2() == 10, "");
+
+#endif
+
+};
diff --git a/clang/test/SemaCXX/constexpr-factorial.cpp b/clang/test/SemaCXX/constexpr-factorial.cpp
index b6cdde59d3fa2..3f9928bb20ea7 100644
--- a/clang/test/SemaCXX/constexpr-factorial.cpp
+++ b/clang/test/SemaCXX/constexpr-factorial.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -std=c++11 -fsyntax-only %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fexperimental-new-constant-interpreter %s
constexpr unsigned oddfac(unsigned n) {
return n == 1 ? 1 : n * oddfac(n-2);
More information about the cfe-commits
mailing list