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); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits