[clang] 0b34d7e - [clang][Interp] Fix calling static operators

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 19 01:34:42 PST 2024


Author: Timm Bäder
Date: 2024-02-19T10:34:18+01:00
New Revision: 0b34d7e9e2915510088aeee5592a845edd62b8ba

URL: https://github.com/llvm/llvm-project/commit/0b34d7e9e2915510088aeee5592a845edd62b8ba
DIFF: https://github.com/llvm/llvm-project/commit/0b34d7e9e2915510088aeee5592a845edd62b8ba.diff

LOG: [clang][Interp] Fix calling static operators

They don't have an instance pointer anywhere but get one passed
via their CallExpr.

Added: 
    

Modified: 
    clang/lib/AST/Interp/ByteCodeExprGen.cpp
    clang/test/AST/Interp/cxx23.cpp
    clang/test/SemaCXX/cxx23-static-callop-lambda-expression.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index a778c300fc33a0..4316596bb32a56 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -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;
   }

diff  --git a/clang/test/AST/Interp/cxx23.cpp b/clang/test/AST/Interp/cxx23.cpp
index a50a9b7183699a..f1df936a5abe74 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 fab76ffc423a3b..2b89e7a3a71291 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; }; 


        


More information about the cfe-commits mailing list