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->getFunction()->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 > 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->getReturnType()->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
