Skip to content

[BUG]: Possible 3.1.0 regression when returning an object that has a copy constructor but no move constructor #6142

Description

@leakec

Required prerequisites

What version (or hash if on master) of pybind11 are you using?

3.1.0

Problem description

When returning an object that has a copy constructor, but no move constructor, I get a complier error in function_ref. This was not present in 3.0.4.

The code to produce the bug is given below. I've also included this tarball with all the files shown below to make re-producing the bug simple:
example.tar.gz

Reproducible example code

example.h

#pragma once

class A {
  public:
    A(int x_value) : x(x_value) {}

    A(const A &) = default;
    A &operator=(const A &) = delete;
    A(A &&) = delete;
    A &operator=(A &&) = delete;

    int x;
};

class B {
  public:
    A getA() const {
        return A(3);
    }
};

module.cc

#include "example.h"
#include <pybind11/pybind11.h>

namespace py = pybind11;

PYBIND11_MODULE(copy_elision_test, module) {
    py::class_<A>(module, "A").def_readonly("x", &A::x);

    py::class_<B>(module, "B").def(py::init<>()).def("getA", &B::getA);
}

CMakeLists.txt

# Builds and registers the minimal pybind11 copy-elision regression test.
cmake_minimum_required(VERSION 3.15)
project(pybind11_copy_elision_regression LANGUAGES CXX)

# Generate compile_commands.json for static-analysis tooling.
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

# Prefer an activated virtual environment when selecting the Python interpreter.
set(PYBIND11_FINDPYTHON ON)
set(Python_FIND_VIRTUALENV FIRST)
find_package(Python COMPONENTS Interpreter Development.Module REQUIRED)

# Ask the selected Python installation where its pybind11 CMake package lives.
execute_process(
    COMMAND "${Python_EXECUTABLE}" -m pybind11 --cmakedir
    OUTPUT_VARIABLE pybind11_DIR
    OUTPUT_STRIP_TRAILING_WHITESPACE
    COMMAND_ERROR_IS_FATAL ANY
)

# Use C++17 because guaranteed prvalue copy elision is the behavior under test.
find_package(pybind11 CONFIG REQUIRED)

pybind11_add_module(copy_elision_test module.cc)
target_compile_features(copy_elision_test PRIVATE cxx_std_17)
target_compile_options(copy_elision_test PRIVATE -Wall -Wextra -Wpedantic -Werror)

run_me - Shell script to run everything

#!/bin/bash

uv venv -p 3.12 .venv
source .venv/bin/activate

uv pip install pybind11==3.0.4
cmake -B build_3.0.4 -S .
cmake --build build_3.0.4

uv pip install pybind11==3.1.0
cmake -B build_3.1.0 -S .
cmake --build build_3.1.0

Is this a regression? Put the last known working version here if it is.

3.0.4

Metadata

Metadata

Assignees

No one assigned

    Labels

    triageNew bug, unverified

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions