Skip to content

[Coverity] Move from a user-supplied l-value reference #20722

@AlexeySachkov

Description

@AlexeySachkov

This is reported as CID 535449, you can find Coverity issues at https://scan.coverity.com/projects/intel-llvm?tab=overview

template <typename FuncT>
std::enable_if_t<detail::check_fn_signature<std::remove_reference_t<FuncT>,
void()>::value ||
detail::check_fn_signature<std::remove_reference_t<FuncT>,
void(interop_handle)>::value>
host_task_impl(FuncT &&Func) {
throwIfActionIsCreated();
// Need to copy these rather than move so that we can check associated
// accessors during finalize
setArgsToAssociatedAccessors();
SetHostTask(std::move(Func));
}

We accept Func argument as a universal reference, meaning that an end user can supply us with an l-value reference:

host_task(FuncT &&Func) {
host_task_impl(Func);
}

Which we will then move, thus creating a potentially unexpected side effect. In the example below the second cout results in nulltpr.

#include <sycl/sycl.hpp>

struct Functor {
  Functor() : ptr(new int(42)) {}
  Functor(const Functor &other) : ptr(new int) {
    *ptr = *other.ptr;
  }

  Functor(Functor &&other) {
    ptr = other.ptr;
    other.ptr = nullptr;
  }

  void operator()() const {}

  ~Functor() {
    if (ptr)
      delete ptr;
  }

  int *ptr;
};

int main() {

  sycl::queue q;

  Functor f;

  std::cout << "f.ptr = " << f.ptr << std::endl;

  q.submit([&](sycl::handler &cgh) {
    cgh.host_task(f);
  });

  std::cout << "f.ptr = " << f.ptr << std::endl;

  return 0;
}

The spec does not seem to be clear about whether or not it is valid for the implementation to leave the input object in an unspecified state.
Related discussions:

Tagging @aelovikov-intel for awareness.

Without the spec clarification we should probably avoid doing std::moves, switch to std::forward and provide a library entry point which accepts a regular reference (because today we only provide one for the universal reference).

Metadata

Metadata

Assignees

No one assigned

    Labels

    CoveritybugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions