https://github.com/Serosh-commits updated 
https://github.com/llvm/llvm-project/pull/176590

>From f234dea1136787b50ffd9deb2f49bfb2dd6ca2f4 Mon Sep 17 00:00:00 2001
From: Serosh <[email protected]>
Date: Sun, 18 Jan 2026 14:42:25 +0530
Subject: [PATCH] [clang][bytecode] Fix crash in void functions returning
 non-void expr

The bytecode compiler was incorrectly emitting an RVOPtr opcode for void 
functions if the return expression had a non-void type. This triggered an 
assertion in the interpreter.

This patch updates visitReturnStmt to check if the expression contains errors 
(RE->containsErrors()) or if the return type is void, and uses discard() for 
the expression in these contexts, preventing erroneous RVO pathing.

Fixes #176536
---
 clang/lib/AST/ByteCode/Compiler.cpp   | 25 +++++++++++++++----------
 clang/test/AST/ByteCode/functions.cpp |  7 +++++++
 2 files changed, 22 insertions(+), 10 deletions(-)

diff --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index 21f8db06919ed..36d6f3f91e237 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -1083,20 +1083,22 @@ bool Compiler<Emitter>::VisitPointerArithBinOp(const 
BinaryOperator *E) {
   if (Op == BO_Add) {
     if (!this->emitAddOffset(OffsetType, E))
       return false;
-
-    if (classifyPrim(E) != PT_Ptr)
-      return this->emitDecayPtr(PT_Ptr, classifyPrim(E), E);
-    return true;
-  }
-  if (Op == BO_Sub) {
+  } else if (Op == BO_Sub) {
     if (!this->emitSubOffset(OffsetType, E))
       return false;
+  } else {
+    return false;
+  }
 
-    if (classifyPrim(E) != PT_Ptr)
-      return this->emitDecayPtr(PT_Ptr, classifyPrim(E), E);
-    return true;
+  if (classifyPrim(E) != PT_Ptr) {
+    if (!this->emitDecayPtr(PT_Ptr, classifyPrim(E), E))
+      return false;
   }
 
+  if (DiscardResult)
+    return this->emitPop(classifyPrim(E), E);
+  return true;
+
   return false;
 }
 
@@ -5678,7 +5680,10 @@ bool Compiler<Emitter>::visitReturnStmt(const ReturnStmt 
*RS) {
       return this->emitRet(*ReturnType, RS);
     }
 
-    if (RE->getType()->isVoidType()) {
+    if (RE->containsErrors()) {
+      if (!this->discard(RE))
+        return false;
+    } else if (RE->getType()->isVoidType()) {
       if (!this->visit(RE))
         return false;
     } else {
diff --git a/clang/test/AST/ByteCode/functions.cpp 
b/clang/test/AST/ByteCode/functions.cpp
index 21d3ddaafaee3..a094767d04503 100644
--- a/clang/test/AST/ByteCode/functions.cpp
+++ b/clang/test/AST/ByteCode/functions.cpp
@@ -735,3 +735,10 @@ namespace PtrPtrCast {
   void foo() { ; }
   void bar(int *a) { a = (int *)(void *)(foo); }
 }
+
+namespace GH176536 {
+  constexpr void foo(int n) {
+    return n > 1 ? foo(n - 1) : 0; // both-error {{return type 'void' must 
match the return type 'int' of the expression}}
+  }
+  static_assert((foo(2), true), "");
+}

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

Reply via email to