llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Serosh (Serosh-commits)

<details>
<summary>Changes</summary>

This patch addresses a crash in the new bytecode interpreter that occurs when a 
void function contains a return statement with a non-void expression (for 
example, a conditional operator where one branch has a side-effect and the 
other returns a value).

The Problem: The crash was triggered by an assertion failure in 
RVOPtr
: Assertion S.Current-&gt;getFunction()-&gt;hasRVO() failed.

In the bytecode compiler’s 
visitReturnStmt
, the logic was previously checking the type of the return expression rather 
than the return type of the function itself. If the expression had a non-void 
type (like the 
int
 in the reproducer return n &gt; 1 ? foo(n-1) : 0;), the compiler would attempt 
to emit an 
RVOPtr
 opcode. Since void functions do not (and should not) have RVO metadata, the 
interpreter would hit the assertion.

The Fix: I've updated 
visitReturnStmt
 to explicitly check CompilingFunction-&gt;getReturnType()-&gt;isVoidType().

If the function is void, we now use 
discard()
 on the return expression. This ensures the expression is still evaluated for 
its side effects (if any) but its result is properly popped from the stack, and 
no RVO pointer is expected.
This prevents the compiler from falling through to the RVO initialization path 
for functions that cannot return a value.
Testing: I've added a regression test in 
clang/test/AST/ByteCode/gh176536.cpp
 using the reported reproducer. The test confirms that we now correctly handle 
the mismatch and emit the appropriate diagnostic instead of crashing the 
frontend.

Fixes #<!-- -->176536



---
Full diff: https://github.com/llvm/llvm-project/pull/176550.diff


2 Files Affected:

- (modified) clang/lib/AST/ByteCode/Compiler.cpp (+3-2) 
- (added) clang/test/AST/ByteCode/gh176536.cpp (+6) 


``````````diff
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp 
b/clang/lib/AST/ByteCode/Compiler.cpp
index 21f8db06919ed..623ba7380e1f3 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -5678,8 +5678,9 @@ bool Compiler<Emitter>::visitReturnStmt(const ReturnStmt 
*RS) {
       return this->emitRet(*ReturnType, RS);
     }
 
-    if (RE->getType()->isVoidType()) {
-      if (!this->visit(RE))
+    if (RE->getType()->isVoidType() ||
+        (CompilingFunction && 
CompilingFunction->getReturnType()->isVoidType())) {
+      if (!this->discard(RE))
         return false;
     } else {
       InitLinkScope<Emitter> ILS(this, InitLink::RVO());
diff --git a/clang/test/AST/ByteCode/gh176536.cpp 
b/clang/test/AST/ByteCode/gh176536.cpp
new file mode 100644
index 0000000000000..2ee45c14cae48
--- /dev/null
+++ b/clang/test/AST/ByteCode/gh176536.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -verify %s
+
+constexpr void foo(int n) {
+  return n > 1 ? foo(n - 1) : 0; // expected-error {{return type 'void' must 
match the return type 'int' of the expression}}
+}
+static_assert((foo(2), true), "");

``````````

</details>


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

Reply via email to