tbaeder updated this revision to Diff 464165.
tbaeder marked 3 inline comments as done.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D134801/new/
https://reviews.llvm.org/D134801
Files:
clang/lib/AST/Interp/ByteCodeExprGen.cpp
clang/lib/AST/Interp/ByteCodeExprGen.h
clang/test/AST/Interp/literals.cpp
clang/test/SemaCXX/constexpr-factorial.cpp
Index: clang/test/SemaCXX/constexpr-factorial.cpp
===================================================================
--- clang/test/SemaCXX/constexpr-factorial.cpp
+++ 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);
Index: clang/test/AST/Interp/literals.cpp
===================================================================
--- clang/test/AST/Interp/literals.cpp
+++ clang/test/AST/Interp/literals.cpp
@@ -190,3 +190,54 @@
constexpr long unsigned RHS = 3;
static_assert(LHS / RHS == 4, "");
};
+
+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
+
+};
Index: clang/lib/AST/Interp/ByteCodeExprGen.h
===================================================================
--- clang/lib/AST/Interp/ByteCodeExprGen.h
+++ clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -88,6 +88,7 @@
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;
Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp
===================================================================
--- clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -344,6 +344,37 @@
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);
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits