Timm =?utf-8?q?Bäder?= <[email protected]>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/[email protected]>


https://github.com/tbaederr updated 
https://github.com/llvm/llvm-project/pull/177384

>From 9d581a96fcc747d4df738967da9a6240efc04571 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]>
Date: Thu, 22 Jan 2026 16:40:06 +0100
Subject: [PATCH 1/2] asdfasdf

---
 clang/lib/AST/ByteCode/Compiler.cpp   |  7 ++++++-
 clang/lib/AST/ByteCode/Interp.cpp     | 11 +++++------
 clang/lib/AST/ByteCode/Interp.h       | 10 ++++++++++
 clang/lib/AST/ByteCode/Opcodes.td     |  2 ++
 clang/test/AST/ByteCode/functions.cpp | 24 ++++++++++++++++++++++++
 5 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index bbc0f5058e6f9..5b276fedfeeaf 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -6468,10 +6468,15 @@ bool Compiler<Emitter>::compileConstructor(const 
CXXConstructorDecl *Ctor) {
     if (!Scope.destroyLocals())
       return false;
   }
+  if (const auto *Body = cast_if_present<CompoundStmt>(Ctor->getBody());
+      Body && !Body->body_empty()) {
+
+    if (!this->emitCtorCheck(SourceInfo{}))
+      return false;
 
-  if (const auto *Body = Ctor->getBody())
     if (!visitStmt(Body))
       return false;
+  }
 
   return this->emitRetVoid(SourceInfo{});
 }
diff --git a/clang/lib/AST/ByteCode/Interp.cpp 
b/clang/lib/AST/ByteCode/Interp.cpp
index 4a98de1e75ecc..49c23e59cb0e0 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1671,12 +1671,11 @@ bool Call(InterpState &S, CodePtr OpPC, const Function 
*Func,
   if (!CheckCallable(S, OpPC, Func))
     return cleanup();
 
-  // FIXME: The isConstructor() check here is not always right. The current
-  // constant evaluator is somewhat inconsistent in when it allows a function
-  // call when checking for a constant expression.
-  if (Func->hasThisPointer() && S.checkingPotentialConstantExpression() &&
-      !Func->isConstructor())
-    return cleanup();
+  // Do not evaluate any function calls in checkingPotentialConstantExpression
+  // mode. Constructors will be aborted later when their initializers are
+  // evaluated.
+  if (S.checkingPotentialConstantExpression() && !Func->isConstructor())
+    return false;
 
   if (!CheckCallDepth(S, OpPC))
     return cleanup();
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 2d8cccb8095a4..92e8266aa172b 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -3297,6 +3297,16 @@ inline bool SideEffect(InterpState &S, CodePtr OpPC) {
   return S.noteSideEffect();
 }
 
+/// Abort without a diagnostic if we're checking for a potential constant
+/// expression and this is not the bottom frame. This is used in constructors 
to
+/// allow evaluating their initializers but abort if we encounter anything in
+/// their body.
+inline bool CtorCheck(InterpState &S, CodePtr OpPC) {
+  if (S.checkingPotentialConstantExpression() && !S.Current->isBottomFrame())
+    return false;
+  return true;
+}
+
 inline bool CheckBitCast(InterpState &S, CodePtr OpPC, const Type *TargetType,
                          bool SrcIsVoidPtr) {
   const auto &Ptr = S.Stk.peek<Pointer>();
diff --git a/clang/lib/AST/ByteCode/Opcodes.td 
b/clang/lib/AST/ByteCode/Opcodes.td
index 6e768793fcfcf..c3123410d06fe 100644
--- a/clang/lib/AST/ByteCode/Opcodes.td
+++ b/clang/lib/AST/ByteCode/Opcodes.td
@@ -923,5 +923,7 @@ def DiagTypeid : Opcode;
 
 def CheckDestruction : Opcode;
 
+def CtorCheck : Opcode;
+
 def PushCC : Opcode { let Args = [ArgBool]; }
 def PopCC : Opcode;
diff --git a/clang/test/AST/ByteCode/functions.cpp 
b/clang/test/AST/ByteCode/functions.cpp
index 21d3ddaafaee3..6d3c03cc1e348 100644
--- a/clang/test/AST/ByteCode/functions.cpp
+++ b/clang/test/AST/ByteCode/functions.cpp
@@ -735,3 +735,27 @@ namespace PtrPtrCast {
   void foo() { ; }
   void bar(int *a) { a = (int *)(void *)(foo); }
 }
+
+namespace NestedDiags {
+  constexpr int foo() { // both-error {{never produces a constant expression}}
+    throw; // both-note {{not valid in a constant expression}} \
+           // both-error {{cannot use 'throw' with exceptions disabled}}
+    return 0;
+  }
+  constexpr int bar() {
+    foo();
+    return 0;
+  }
+
+
+  struct S {
+    constexpr S() { // both-error {{never produces a constant expression}}
+      throw; // both-note {{not valid in a constant expression}} \
+             // both-error {{cannot use 'throw' with exceptions disabled}}
+    }
+  };
+  constexpr bool callS() {
+    S s;
+    return true;
+  }
+}

>From 5aa7e88038d3901763bea81a0b063f5092ffdeda Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <[email protected]>
Date: Fri, 23 Jan 2026 06:51:31 +0100
Subject: [PATCH 2/2] Emit CtorCheck op also for non-CompundStmt bodies

---
 clang/lib/AST/ByteCode/Compiler.cpp | 14 ++++++++++----
 clang/test/AST/ByteCode/cxx23.cpp   | 15 +++++++++++++++
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index 5b276fedfeeaf..236f79c002301 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -6468,11 +6468,17 @@ bool Compiler<Emitter>::compileConstructor(const 
CXXConstructorDecl *Ctor) {
     if (!Scope.destroyLocals())
       return false;
   }
-  if (const auto *Body = cast_if_present<CompoundStmt>(Ctor->getBody());
-      Body && !Body->body_empty()) {
 
-    if (!this->emitCtorCheck(SourceInfo{}))
-      return false;
+  if (const Stmt *Body = Ctor->getBody()) {
+    // Only emit the CtorCheck op for non-empty CompoundStmt bodies.
+    // For non-CompoundStmts, always assume they are non-empty and emit it.
+    if (const auto *CS = dyn_cast<CompoundStmt>(Body)) {
+      if (!CS->body_empty() && !this->emitCtorCheck(SourceInfo{}))
+        return false;
+    } else {
+      if (!this->emitCtorCheck(SourceInfo{}))
+        return false;
+    }
 
     if (!visitStmt(Body))
       return false;
diff --git a/clang/test/AST/ByteCode/cxx23.cpp 
b/clang/test/AST/ByteCode/cxx23.cpp
index 8139451400cae..e3be7887c357e 100644
--- a/clang/test/AST/ByteCode/cxx23.cpp
+++ b/clang/test/AST/ByteCode/cxx23.cpp
@@ -579,3 +579,18 @@ namespace UnknownParams {
     return 1;
   }
 }
+
+namespace NonCompoundStmtBody {
+  /// The body of the constructor is NOT a CompoundStmt.
+  struct S {
+    constexpr S() try { x = 20; } catch(...) {}
+
+    int x = 0;
+  };
+
+  constexpr bool testS() {
+    S s;
+    return s.x == 20;
+  }
+  static_assert(testS());
+}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to