Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Clang] Fix immediate escalation of template function specializations. #124404

Merged
merged 2 commits into from
Jan 27, 2025

Conversation

cor3ntin
Copy link
Contributor

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

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.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jan 25, 2025
@llvmbot
Copy link
Member

llvmbot commented Jan 25, 2025

@llvm/pr-subscribers-clang

Author: cor3ntin (cor3ntin)

Changes

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


Full diff: https://github.com/llvm/llvm-project/pull/124404.diff

3 Files Affected:

  • (modified) clang/docs/ReleaseNotes.rst (+1)
  • (modified) clang/lib/AST/Decl.cpp (+4)
  • (modified) clang/test/SemaCXX/cxx2b-consteval-propagate.cpp (+18)
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@-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}}
+}
+
+}

@cor3ntin cor3ntin merged commit 561132e into llvm:main Jan 27, 2025
5 of 7 checks passed
@cor3ntin cor3ntin deleted the gh123405 branch January 27, 2025 14:50
@cor3ntin
Copy link
Contributor Author

I'll push a fix for the build failure on arm shortly

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}}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also have a success case as well for this particular scenario or is that covered by existing tests?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i completely removed the conversion to it, it was not salient to the test. this is just testing that tfn becomes immediate

@nikic
Copy link
Contributor

nikic commented Jan 27, 2025

FYI this change has some measurable compile-time overhead (about 0.2% for debug builds): https://llvm-compile-time-tracker.com/compare.php?from=eaa5897534cbd263d0cdbf780f72133c2fe8d8d4&to=561132e71b29d9b747dfda1509f715847852f77b&stat=instructions:u

Not sure whether that's expected or not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[clang++] Functions aren't marked immediate-escalating
5 participants