Skip to content

Commit 820c6ac

Browse files
authored
[Clang] call HandleImmediateInvocation before checking for immediate escacalating expressions (reland) (#124708)
HandleImmediateInvocation can call MarkExpressionAsImmediateEscalating and should always be called before CheckImmediateEscalatingFunctionDefinition. However, we were not doing that in `ActFunctionBody`. Fixes #119046
1 parent 78b5bb7 commit 820c6ac

File tree

4 files changed

+52
-1
lines changed

4 files changed

+52
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,6 +1036,7 @@ Bug Fixes to C++ Support
10361036
- Fix type of expression when calling a template which returns an ``__array_rank`` querying a type depending on a
10371037
template parameter. Now, such expression can be used with ``static_assert`` and ``constexpr``. (#GH123498)
10381038
- Correctly determine the implicit constexprness of lambdas in dependent contexts. (#GH97958) (#GH114234)
1039+
- Fix that some dependent immediate expressions did not cause immediate escalation (#GH119046)
10391040

10401041
Bug Fixes to AST Handling
10411042
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaDecl.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16019,7 +16019,6 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
1601916019
if (!FD->isDeletedAsWritten())
1602016020
FD->setBody(Body);
1602116021
FD->setWillHaveBody(false);
16022-
CheckImmediateEscalatingFunctionDefinition(FD, FSI);
1602316022

1602416023
if (getLangOpts().CPlusPlus14) {
1602516024
if (!FD->isInvalidDecl() && Body && !FD->isDependentContext() &&
@@ -16397,6 +16396,9 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
1639716396
// the declaration context below. Otherwise, we're unable to transform
1639816397
// 'this' expressions when transforming immediate context functions.
1639916398

16399+
if (FD)
16400+
CheckImmediateEscalatingFunctionDefinition(FD, getCurFunction());
16401+
1640016402
if (!IsInstantiation)
1640116403
PopDeclContext();
1640216404

clang/test/CodeGenCXX/gh119046.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// RUN: %clang_cc1 -std=c++2a -triple x86_64-elf-gnu %s -emit-llvm -o - | FileCheck %s
2+
3+
struct S {
4+
consteval void operator()() {}
5+
};
6+
7+
template <class Fn>
8+
constexpr void dispatch(Fn fn) {
9+
fn();
10+
}
11+
12+
template <class Visitor>
13+
struct value_visitor {
14+
constexpr void operator()() { visitor(); }
15+
Visitor&& visitor;
16+
};
17+
18+
template <class Visitor>
19+
constexpr auto make_dispatch() {
20+
return dispatch<value_visitor<S>>;
21+
}
22+
23+
template <class Visitor>
24+
constexpr void visit(Visitor&&) {
25+
make_dispatch<Visitor>();
26+
}
27+
28+
void f() { visit(S{}); }
29+
30+
// CHECK: define {{.*}} @_Z1fv
31+
// CHECK-NOT: define {{.*}} @_Z5visitI1SEvOT_
32+
// CHECK-NOT: define {{.*}} @_Z13make_dispatchI1SEDav

clang/test/SemaCXX/cxx2b-consteval-propagate.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,3 +560,19 @@ void foo() {
560560
S s;
561561
}
562562
} // namespace GH118000
563+
564+
namespace GH119046 {
565+
566+
template <typename Cls> constexpr auto tfn(int) {
567+
return (unsigned long long)(&Cls::sfn);
568+
//expected-note@-1 {{'tfn<GH119046::S>' is an immediate function because its body evaluates the address of a consteval function 'sfn'}}
569+
};
570+
struct S { static consteval void sfn() {} };
571+
572+
int f() {
573+
int a = 0; // expected-note{{declared here}}
574+
return tfn<S>(a);
575+
//expected-error@-1 {{call to immediate function 'GH119046::tfn<GH119046::S>' is not a constant expression}}
576+
//expected-note@-2 {{read of non-const variable 'a' is not allowed in a constant expression}}
577+
}
578+
}

0 commit comments

Comments
 (0)