[clang] a4f8590 - [clang] Allow consteval functions in default arguments

Chuanqi Xu via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 6 19:56:28 PDT 2022


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;


        


More information about the cfe-commits mailing list