root icon indicating copy to clipboard operation
root copied to clipboard

Cling doesn't play nice with template arguments after a parameter pack

Open bendavid opened this issue 2 years ago • 2 comments

Consider the following test case:

test.c

#include "TInterpreter.h"
#include "TClass.h"
#include "TMethod.h"
#include "TROOT.h"
#include <iostream>

struct Dummy {
  double x;
};

struct Dummy2{
};

template<typename... Args, typename Extra = Dummy2>
double sumT(Args... args) {
  return (args.x + ...);
}

int test() {
  auto meth_explicit = gROOT->GetGlobalFunctionWithPrototype("sumT", "Dummy, Dummy, Dummy");
  TMethodCall call_explicit(meth_explicit);

  double res;
  const Dummy arg{5.};
  const void *args[3] = {&arg, &arg, &arg};
  call_explicit.Execute(nullptr, args, 3,  &res);
  std::cout << "res = " << res << std::endl;

  return 0;
}

The attempted call fails, because the "extra" template argument is explicitly appended to the list of template arguments when the call wrapper is compiled. (This issue prevents templated functions with this feature being called from PyROOT)

In file included from input_line_8:1:
/home/b/bendavid/pyrootdebug7/test.c:16:16: error: no member named 'x' in 'Dummy2'
  return (args.x + ...);
          ~~~~ ^
input_line_10:8:17: note: in instantiation of function template specialization 'sumT<Dummy, Dummy, Dummy, Dummy2, Dummy2>' requested here
         Dummy))sumT<Dummy, Dummy, Dummy, Dummy2>)(*(Dummy*)args[0], *(Dummy*)args[1],
                ^
Error in <TClingCallFunc::make_wrapper>: Failed to compile
  ==== SOURCE BEGIN ====
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-security"
__attribute__((used)) __attribute__((annotate("__cling__ptrcheck(off)")))
extern "C" void __cf_0(void* obj, int nargs, void** args, void* ret)
{
   if (ret) {
      new (ret) (double) (((double (&)(Dummy, Dummy,
         Dummy))sumT<Dummy, Dummy, Dummy, Dummy2>)(*(Dummy*)args[0], *(Dummy*)args[1],
         *(Dummy*)args[2]));
      return;
   }
   else {
      (void)(((double (&)(Dummy, Dummy,
         Dummy))sumT<Dummy, Dummy, Dummy, Dummy2>)(*(Dummy*)args[0], *(Dummy*)args[1],
         *(Dummy*)args[2]));
      return;
   }
}
#pragma clang diagnostic pop
  ==== SOURCE END ====
Error in <TClingCallFunc::ExecWithArgsAndReturn(address, args, ret)>: Called with no wrapper, not implemented!
res = 7.31217e-322
(int) 0

bendavid avatar Mar 27 '23 00:03 bendavid

Still same issue after the upgrade to LLVM 16. As this involves TClingCallFunc, I'm adding Vassil here

hahnjo avatar Dec 11 '23 13:12 hahnjo

Just confirming this is still a problem in current nightlies.

bendavid avatar Oct 02 '24 12:10 bendavid