Skip to content

Commit 0b34d7e

Browse files
committed
[clang][Interp] Fix calling static operators
They don't have an instance pointer anywhere but get one passed via their CallExpr.
1 parent 4b9c089 commit 0b34d7e

File tree

3 files changed

+44
-6
lines changed

3 files changed

+44
-6
lines changed

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1716,6 +1716,9 @@ bool ByteCodeExprGen<Emitter>::VisitTypeTraitExpr(const TypeTraitExpr *E) {
17161716

17171717
template <class Emitter>
17181718
bool ByteCodeExprGen<Emitter>::VisitLambdaExpr(const LambdaExpr *E) {
1719+
if (DiscardResult)
1720+
return true;
1721+
17191722
assert(Initializing);
17201723
const Record *R = P.getOrCreateRecord(E->getLambdaClass());
17211724

@@ -2824,14 +2827,28 @@ bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) {
28242827
}
28252828
}
28262829

2830+
auto Args = E->arguments();
2831+
// Calling a static operator will still
2832+
// pass the instance, but we don't need it.
2833+
// Discard it here.
2834+
if (isa<CXXOperatorCallExpr>(E)) {
2835+
if (const auto *MD =
2836+
dyn_cast_if_present<CXXMethodDecl>(E->getDirectCallee());
2837+
MD && MD->isStatic()) {
2838+
if (!this->discard(E->getArg(0)))
2839+
return false;
2840+
Args = drop_begin(Args, 1);
2841+
}
2842+
}
2843+
28272844
// Add the (optional, implicit) This pointer.
28282845
if (const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
28292846
if (!this->visit(MC->getImplicitObjectArgument()))
28302847
return false;
28312848
}
28322849

28332850
// Put arguments on the stack.
2834-
for (const auto *Arg : E->arguments()) {
2851+
for (const auto *Arg : Args) {
28352852
if (!this->visit(Arg))
28362853
return false;
28372854
}

clang/test/AST/Interp/cxx23.cpp

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions -verify=ref20 %s
2-
// RUN: %clang_cc1 -std=c++23 -fsyntax-only -fcxx-exceptions -verify=ref23 %s
3-
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions -verify=expected20 %s -fexperimental-new-constant-interpreter
4-
// RUN: %clang_cc1 -std=c++23 -fsyntax-only -fcxx-exceptions -verify=expected23 %s -fexperimental-new-constant-interpreter
1+
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions -verify=ref20,all %s
2+
// RUN: %clang_cc1 -std=c++23 -fsyntax-only -fcxx-exceptions -verify=ref23,all %s
3+
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions -verify=expected20,all %s -fexperimental-new-constant-interpreter
4+
// RUN: %clang_cc1 -std=c++23 -fsyntax-only -fcxx-exceptions -verify=expected23,all %s -fexperimental-new-constant-interpreter
55

66
/// FIXME: The new interpreter is missing all the 'control flows through...' diagnostics.
77

@@ -123,3 +123,24 @@ namespace StaticLambdas {
123123
}
124124
static_assert(capture_constexpr());
125125
}
126+
127+
namespace StaticOperators {
128+
auto lstatic = []() static { return 3; }; // ref20-warning {{C++23 extension}} \
129+
// expected20-warning {{C++23 extension}}
130+
static_assert(lstatic() == 3, "");
131+
constexpr int (*f2)(void) = lstatic;
132+
static_assert(f2() == 3);
133+
134+
struct S1 {
135+
constexpr S1() { // all-error {{never produces a constant expression}}
136+
throw; // all-note 2{{not valid in a constant expression}}
137+
}
138+
static constexpr int operator()() { return 3; } // ref20-warning {{C++23 extension}} \
139+
// expected20-warning {{C++23 extension}}
140+
};
141+
static_assert(S1{}() == 3, ""); // all-error {{not an integral constant expression}} \
142+
// all-note {{in call to}}
143+
144+
145+
146+
}

clang/test/SemaCXX/cxx23-static-callop-lambda-expression.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s
2-
2+
// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s -fexperimental-new-constant-interpreter
33

44
namespace ns1 {
55
auto lstatic = []() static { return 3; };

0 commit comments

Comments
 (0)