mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-25 13:46:07 +00:00
[clang][Interp] Fix calling static operators
They don't have an instance pointer anywhere but get one passed via their CallExpr.
This commit is contained in:
parent
4b9c089381
commit
0b34d7e9e2
@ -1716,6 +1716,9 @@ bool ByteCodeExprGen<Emitter>::VisitTypeTraitExpr(const TypeTraitExpr *E) {
|
||||
|
||||
template <class Emitter>
|
||||
bool ByteCodeExprGen<Emitter>::VisitLambdaExpr(const LambdaExpr *E) {
|
||||
if (DiscardResult)
|
||||
return true;
|
||||
|
||||
assert(Initializing);
|
||||
const Record *R = P.getOrCreateRecord(E->getLambdaClass());
|
||||
|
||||
@ -2824,6 +2827,20 @@ bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) {
|
||||
}
|
||||
}
|
||||
|
||||
auto Args = E->arguments();
|
||||
// Calling a static operator will still
|
||||
// pass the instance, but we don't need it.
|
||||
// Discard it here.
|
||||
if (isa<CXXOperatorCallExpr>(E)) {
|
||||
if (const auto *MD =
|
||||
dyn_cast_if_present<CXXMethodDecl>(E->getDirectCallee());
|
||||
MD && MD->isStatic()) {
|
||||
if (!this->discard(E->getArg(0)))
|
||||
return false;
|
||||
Args = drop_begin(Args, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the (optional, implicit) This pointer.
|
||||
if (const auto *MC = dyn_cast<CXXMemberCallExpr>(E)) {
|
||||
if (!this->visit(MC->getImplicitObjectArgument()))
|
||||
@ -2831,7 +2848,7 @@ bool ByteCodeExprGen<Emitter>::VisitCallExpr(const CallExpr *E) {
|
||||
}
|
||||
|
||||
// Put arguments on the stack.
|
||||
for (const auto *Arg : E->arguments()) {
|
||||
for (const auto *Arg : Args) {
|
||||
if (!this->visit(Arg))
|
||||
return false;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions -verify=ref20 %s
|
||||
// RUN: %clang_cc1 -std=c++23 -fsyntax-only -fcxx-exceptions -verify=ref23 %s
|
||||
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions -verify=expected20 %s -fexperimental-new-constant-interpreter
|
||||
// RUN: %clang_cc1 -std=c++23 -fsyntax-only -fcxx-exceptions -verify=expected23 %s -fexperimental-new-constant-interpreter
|
||||
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions -verify=ref20,all %s
|
||||
// RUN: %clang_cc1 -std=c++23 -fsyntax-only -fcxx-exceptions -verify=ref23,all %s
|
||||
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -fcxx-exceptions -verify=expected20,all %s -fexperimental-new-constant-interpreter
|
||||
// RUN: %clang_cc1 -std=c++23 -fsyntax-only -fcxx-exceptions -verify=expected23,all %s -fexperimental-new-constant-interpreter
|
||||
|
||||
/// FIXME: The new interpreter is missing all the 'control flows through...' diagnostics.
|
||||
|
||||
@ -123,3 +123,24 @@ namespace StaticLambdas {
|
||||
}
|
||||
static_assert(capture_constexpr());
|
||||
}
|
||||
|
||||
namespace StaticOperators {
|
||||
auto lstatic = []() static { return 3; }; // ref20-warning {{C++23 extension}} \
|
||||
// expected20-warning {{C++23 extension}}
|
||||
static_assert(lstatic() == 3, "");
|
||||
constexpr int (*f2)(void) = lstatic;
|
||||
static_assert(f2() == 3);
|
||||
|
||||
struct S1 {
|
||||
constexpr S1() { // all-error {{never produces a constant expression}}
|
||||
throw; // all-note 2{{not valid in a constant expression}}
|
||||
}
|
||||
static constexpr int operator()() { return 3; } // ref20-warning {{C++23 extension}} \
|
||||
// expected20-warning {{C++23 extension}}
|
||||
};
|
||||
static_assert(S1{}() == 3, ""); // all-error {{not an integral constant expression}} \
|
||||
// all-note {{in call to}}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s
|
||||
|
||||
// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify %s -fexperimental-new-constant-interpreter
|
||||
|
||||
namespace ns1 {
|
||||
auto lstatic = []() static { return 3; };
|
||||
|
Loading…
x
Reference in New Issue
Block a user