diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index a778c300fc33..4316596bb32a 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1716,6 +1716,9 @@ bool ByteCodeExprGen::VisitTypeTraitExpr(const TypeTraitExpr *E) { template bool ByteCodeExprGen::VisitLambdaExpr(const LambdaExpr *E) { + if (DiscardResult) + return true; + assert(Initializing); const Record *R = P.getOrCreateRecord(E->getLambdaClass()); @@ -2824,6 +2827,20 @@ bool ByteCodeExprGen::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(E)) { + if (const auto *MD = + dyn_cast_if_present(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(E)) { if (!this->visit(MC->getImplicitObjectArgument())) @@ -2831,7 +2848,7 @@ bool ByteCodeExprGen::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; } diff --git a/clang/test/AST/Interp/cxx23.cpp b/clang/test/AST/Interp/cxx23.cpp index a50a9b718369..f1df936a5abe 100644 --- a/clang/test/AST/Interp/cxx23.cpp +++ b/clang/test/AST/Interp/cxx23.cpp @@ -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}} + + + +} diff --git a/clang/test/SemaCXX/cxx23-static-callop-lambda-expression.cpp b/clang/test/SemaCXX/cxx23-static-callop-lambda-expression.cpp index fab76ffc423a..2b89e7a3a712 100644 --- a/clang/test/SemaCXX/cxx23-static-callop-lambda-expression.cpp +++ b/clang/test/SemaCXX/cxx23-static-callop-lambda-expression.cpp @@ -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; };