[clang] [clang][Interp] Fix MemberExpr initializing an existing value (PR #79973)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 30 01:39:54 PST 2024


https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/79973

This is similar to c1ad363e6eba308fa94c47374ee98b3c79693a35, but with the additional twist that initializing an existing value from a `MemberExpr` was not working correctly.

>From 0e729521b99147d66d8a1aa2c4d33326f22c6202 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Tue, 30 Jan 2024 08:50:34 +0100
Subject: [PATCH] [clang][Interp] Fix MemberExpr initializing an existing value

---
 clang/lib/AST/Interp/ByteCodeExprGen.cpp | 9 +++++++--
 clang/test/AST/Interp/cxx98.cpp          | 8 ++++++++
 clang/test/SemaCXX/pr72025.cpp           | 1 +
 3 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index d4501cefb2131..1fd5a2998a0c8 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -1019,7 +1019,7 @@ bool ByteCodeExprGen<Emitter>::VisitMemberExpr(const MemberExpr *E) {
   if (DiscardResult)
     return this->discard(Base);
 
-  if (!this->visit(Base))
+  if (!this->delegate(Base))
     return false;
 
   // Base above gives us a pointer on the stack.
@@ -1507,8 +1507,13 @@ bool ByteCodeExprGen<Emitter>::VisitMaterializeTemporaryExpr(
       return this->emitGetPtrLocal(*LocalIndex, E);
     }
   } else {
+    SmallVector<const Expr *, 2> CommaLHSs;
+    SmallVector<SubobjectAdjustment, 2> Adjustments;
+    const Expr *Inner =
+        E->getSubExpr()->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
+
     if (std::optional<unsigned> LocalIndex =
-            allocateLocal(SubExpr, /*IsExtended=*/true)) {
+            allocateLocal(Inner, /*IsExtended=*/true)) {
       if (!this->emitGetPtrLocal(*LocalIndex, E))
         return false;
       return this->visitInitializer(SubExpr);
diff --git a/clang/test/AST/Interp/cxx98.cpp b/clang/test/AST/Interp/cxx98.cpp
index 79f93c8d78f16..1acc74a8290a0 100644
--- a/clang/test/AST/Interp/cxx98.cpp
+++ b/clang/test/AST/Interp/cxx98.cpp
@@ -30,3 +30,11 @@ int NCI; // both-note {{declared here}}
 int NCIA[NCI]; // both-warning {{variable length array}} \
                // both-error {{variable length array}} \\
                // both-note {{read of non-const variable 'NCI'}}
+
+
+struct V {
+  char c[1];
+  banana V() : c("i") {} // both-error {{unknown type name 'banana'}} \
+                         // both-error {{constructor cannot have a return type}}
+};
+_Static_assert(V().c[0], ""); // both-error {{is not an integral constant expression}}
diff --git a/clang/test/SemaCXX/pr72025.cpp b/clang/test/SemaCXX/pr72025.cpp
index 9f0a4b0f43630..ac55f27728a36 100644
--- a/clang/test/SemaCXX/pr72025.cpp
+++ b/clang/test/SemaCXX/pr72025.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -verify -std=c++03 -fsyntax-only %s
+// RUN: %clang_cc1 -verify -std=c++03 -fsyntax-only -fexperimental-new-constant-interpreter %s
 struct V {
   char c[2];
   banana V() : c("i") {} // expected-error {{unknown type name}}



More information about the cfe-commits mailing list