[clang] [Clang] Fix immediate escalation of template function specializations. (PR #124404)

via cfe-commits cfe-commits at lists.llvm.org
Sat Jan 25 04:48:57 PST 2025


https://github.com/cor3ntin created https://github.com/llvm/llvm-project/pull/124404

We record whether an expression is immediate escalating in the FunctionScope.
However, that only happen when parsing or transforming an expression. This might not happen when transforming a non dependent expression.

This patch fixes that by considering a function immediate when instantiated from an immediate function.

Fixes #123405

>From fa548f2d75fbb6fde21ebbf937a93494e600a6e7 Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Sat, 25 Jan 2025 13:17:27 +0100
Subject: [PATCH] [Clang] Fix immediate escalation.

We record whether an expression is immediate escalating in the
FunctionScope.
However, that only happen when parsing or transforming
an expression. This might not happen when transforming
a non dependent expression.

This patch fixes that by considering a function immediate
when instantiated from an immediate function.
---
 clang/docs/ReleaseNotes.rst                    |  1 +
 clang/lib/AST/Decl.cpp                         |  4 ++++
 .../test/SemaCXX/cxx2b-consteval-propagate.cpp | 18 ++++++++++++++++++
 3 files changed, 23 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e9fffddd507c66..1209ba3ec923d9 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -991,6 +991,7 @@ Bug Fixes to C++ Support
 - Fixed assertions or false compiler diagnostics in the case of C++ modules for
   lambda functions or inline friend functions defined inside templates (#GH122493).
 - Clang now rejects declaring an alias template with the same name as its template parameter. (#GH123423)
+- Fixed immediate escalation of non-dependent expressions. (#GH123405)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 5ce03ce20d2841..4753b1727f0dd4 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -3314,6 +3314,10 @@ bool FunctionDecl::isImmediateFunction() const {
         .getConstructor()
         ->isImmediateFunction();
 
+  if (FunctionDecl *P = getTemplateInstantiationPattern();
+      P && P->isImmediateFunction())
+    return true;
+
   if (const auto *MD = dyn_cast<CXXMethodDecl>(this);
       MD && MD->isLambdaStaticInvoker())
     return MD->getParent()->getLambdaCallOperator()->isImmediateFunction();
diff --git a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp
index 3f3123eaee76b6..222d482f40aa5d 100644
--- a/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp
+++ b/clang/test/SemaCXX/cxx2b-consteval-propagate.cpp
@@ -528,3 +528,21 @@ D d(0); // expected-note {{in implicit initialization for inherited constructor
 // expected-error at -1 {{call to immediate function 'GH112677::D::SimpleCtor' is not a constant expression}}
 
 }
+
+namespace GH123405 {
+
+consteval void fn() {}
+
+template <typename>
+constexpr int tfn(int) {
+    auto p = &fn;  // expected-note {{'tfn<int>' is an immediate function because its body evaluates the address of a consteval function 'fn'}}
+    return int(p); // expected-error {{cast from pointer to smaller type 'int' loses information}}
+}
+
+int g() {
+   int a; // expected-note {{declared here}}
+   return tfn<int>(a); // expected-error {{call to immediate function 'GH123405::tfn<int>' is not a constant expression}}\
+                       // expected-note {{read of non-const variable 'a' is not allowed in a constant expression}}
+}
+
+}



More information about the cfe-commits mailing list