tbaeder updated this revision to Diff 457838. tbaeder added a comment. Add a unit test.
CHANGES SINCE LAST ACTION https://reviews.llvm.org/D132136/new/ https://reviews.llvm.org/D132136 Files: clang/lib/AST/ExprConstant.cpp clang/test/AST/Interp/literals.cpp clang/unittests/AST/EvaluateAsRValueTest.cpp
Index: clang/unittests/AST/EvaluateAsRValueTest.cpp =================================================================== --- clang/unittests/AST/EvaluateAsRValueTest.cpp +++ clang/unittests/AST/EvaluateAsRValueTest.cpp @@ -107,3 +107,50 @@ Args)); } } + +class CheckLValueToRValueConversionVisitor + : public clang::RecursiveASTVisitor<CheckLValueToRValueConversionVisitor> { +public: + bool VisitDeclRefExpr(const clang::DeclRefExpr *E) { + clang::Expr::EvalResult Result; + E->EvaluateAsRValue(Result, E->getDecl()->getASTContext(), true); + + EXPECT_TRUE(Result.Val.hasValue()); + // Since EvaluateAsRValue does an implicit lvalue-to-rvalue conversion, + // the result cannot be a LValue. + EXPECT_FALSE(Result.Val.isLValue()); + + return true; + } +}; + +class CheckConversionAction : public clang::ASTFrontendAction { +public: + std::unique_ptr<clang::ASTConsumer> + CreateASTConsumer(clang::CompilerInstance &Compiler, + llvm::StringRef FilePath) override { + return std::make_unique<Consumer>(); + } + +private: + class Consumer : public clang::ASTConsumer { + public: + ~Consumer() override {} + + void HandleTranslationUnit(clang::ASTContext &Ctx) override { + CheckLValueToRValueConversionVisitor Evaluator; + Evaluator.TraverseDecl(Ctx.getTranslationUnitDecl()); + } + }; +}; + +TEST(EvaluateAsRValue, LValueToRValueConversionWorks) { + std::string ModesToTest[] = {"", "-fexperimental-new-constant-interpreter"}; + for (std::string const &Mode : ModesToTest) { + std::vector<std::string> Args(1, Mode); + ASSERT_TRUE(runToolOnCodeWithArgs(std::make_unique<CheckConversionAction>(), + "constexpr int a = 20;\n" + "static_assert(a == 20, \"\");\n", + Args)); + } +} Index: clang/test/AST/Interp/literals.cpp =================================================================== --- clang/test/AST/Interp/literals.cpp +++ clang/test/AST/Interp/literals.cpp @@ -11,6 +11,7 @@ static_assert(number == 10, ""); static_assert(number != 10, ""); // expected-error{{failed}} \ // ref-error{{failed}} \ + // expected-note{{evaluates to}} \ // ref-note{{evaluates to}} constexpr bool getTrue() { return true; } Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -14934,25 +14934,27 @@ /// lvalue-to-rvalue cast if it is an lvalue. static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result) { assert(!E->isValueDependent()); + + if (E->getType().isNull()) + return false; + + if (!CheckLiteralType(Info, E)) + return false; + if (Info.EnableNewConstInterp) { if (!Info.Ctx.getInterpContext().evaluateAsRValue(Info, E, Result)) return false; } else { - if (E->getType().isNull()) - return false; - - if (!CheckLiteralType(Info, E)) - return false; - if (!::Evaluate(Result, Info, E)) return false; + } - if (E->isGLValue()) { - LValue LV; - LV.setFrom(Info.Ctx, Result); - if (!handleLValueToRValueConversion(Info, E, E->getType(), LV, Result)) - return false; - } + // Implicit lvalue-to-rvalue cast. + if (E->isGLValue()) { + LValue LV; + LV.setFrom(Info.Ctx, Result); + if (!handleLValueToRValueConversion(Info, E, E->getType(), LV, Result)) + return false; } // Check this core constant expression is a constant expression.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits