Author: Evgeny Shulgin Date: 2022-06-07T10:54:37+08:00 New Revision: a4f8590247264b9c3121f48dd5b3db707c934ba2
URL: https://github.com/llvm/llvm-project/commit/a4f8590247264b9c3121f48dd5b3db707c934ba2 DIFF: https://github.com/llvm/llvm-project/commit/a4f8590247264b9c3121f48dd5b3db707c934ba2.diff LOG: [clang] Allow consteval functions in default arguments We should not mark a function as "referenced" if we call it within a ConstantExpr, because the expression will be folded to a value in LLVM IR. To prevent emitting consteval function declarations, we should not "jump over" a ConstantExpr when it is a top-level ParmVarDecl's subexpression. Fixes https://github.com/llvm/llvm-project/issues/48230 Reviewed By: erichkeane, aaron.ballman, ChuanqiXu Differenitial Revision: https://reviews.llvm.org/D119646 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/AST/Decl.cpp clang/lib/Sema/SemaExpr.cpp clang/test/SemaCXX/cxx2a-consteval.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 57519787ecc4..8c4f7f48850f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -166,6 +166,8 @@ Bug Fixes - Allow use of an elaborated type specifier as a ``_Generic`` selection association in C++ mode. This fixes `Issue 55562 <https://github.com/llvm/llvm-project/issues/55562>`_. +- Clang will allow calling a ``consteval`` function in a default argument. This + fixes `Issue 48230 <https://github.com/llvm/llvm-project/issues/48230>`_. Improvements to Clang's diagnostics ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 1c5c64d1b365..bd48a4ab93d1 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2867,7 +2867,8 @@ Expr *ParmVarDecl::getDefaultArg() { Expr *Arg = getInit(); if (auto *E = dyn_cast_or_null<FullExpr>(Arg)) - return E->getSubExpr(); + if (!isa<ConstantExpr>(E)) + return E->getSubExpr(); return Arg; } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 01a3599087f8..9e6a4212b3a1 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -19611,6 +19611,12 @@ class EvaluatedExprMarker : public UsedDeclVisitor<EvaluatedExprMarker> { Inherited::Visit(E); } + void VisitConstantExpr(ConstantExpr *E) { + // Don't mark declarations within a ConstantExpression, as this expression + // will be evaluated and folded to a value. + return; + } + void VisitDeclRefExpr(DeclRefExpr *E) { // If we were asked not to visit local variables, don't. if (SkipLocalVariables) { diff --git a/clang/test/SemaCXX/cxx2a-consteval.cpp b/clang/test/SemaCXX/cxx2a-consteval.cpp index 6b6f8d22cdb8..df2a9925c015 100644 --- a/clang/test/SemaCXX/cxx2a-consteval.cpp +++ b/clang/test/SemaCXX/cxx2a-consteval.cpp @@ -651,6 +651,27 @@ static_assert(baz<int>() == sizeof(int)); } // namespace value_dependent +namespace default_argument { + +// Previously calls of consteval functions in default arguments were rejected. +// Now we show that we don't reject such calls. +consteval int foo() { return 1; } +consteval int bar(int i = foo()) { return i * i; } + +struct Test1 { + Test1(int i = bar(13)) {} + void v(int i = bar(13) * 2 + bar(15)) {} +}; +Test1 t1; + +struct Test2 { + constexpr Test2(int i = bar()) {} + constexpr void v(int i = bar(bar(bar(foo())))) {} +}; +Test2 t2; + +} // namespace default_argument + namespace PR50779 { struct derp { int b = 0; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits