Skip to content

pyroot can trigger clang assertion failure on enum with value too big to fit in int64_t #17697

@scott-snyder

Description

@scott-snyder

Check duplicate issues.

  • Checked for duplicates

Description

In root 6.34.02, trying to use via pyroot a C++ class containing an enum with a value that is too big to fit into a (signed) int64_t will trip an assertion in the dbg build:

python: /build/jenkins/workspace/lcg_release_pipeline/build/projects/ROOT-6.34.02/src/ROOT/6.34.02/interpreter/llvm-project/llvm/include/llvm/ADT/APSInt.h:99: int64_t llvm::APSInt::getExtValue() const: Assertion `isRepresentableByInt64() && "Too many bits for int64_t"' failed.

See the reproducer below.

Here is a partial stack trace:

#4  0x00007ffff76373c6 in __assert_fail () from /lib64/libc.so.6
#5  0x00007fffedeaa1fe in llvm::APSInt::getExtValue (this=0x7fffffff9a20)
    at /build/jenkins/workspace/lcg_release_pipeline/build/projects/ROOT-6.34.02/src/ROOT/6.34.02/interpreter/llvm-project/llvm/include/llvm/ADT/APSInt.h:99
#6  0x00007fffedea92e7 in TClingDataMemberInfo::Offset (this=0x6a278a0)
    at /build/jenkins/workspace/lcg_release_pipeline/build/projects/ROOT-6.34.02/src/ROOT/6.34.02/core/metacling/src/TClingDataMemberInfo.cxx:408
#7  0x00007fffedcf0d28 in TCling::DataMemberInfo_Offset (this=0x5b0c20, 
    dminfo=0x6a278a0)
    at /build/jenkins/workspace/lcg_release_pipeline/build/projects/ROOT-6.34.02/src/ROOT/6.34.02/core/metacling/src/TCling.cxx:8653
#8  0x00007ffff6806e53 in TDataMember::GetOffsetCint (this=0x6ac11a0)
    at /build/jenkins/workspace/lcg_release_pipeline/build/projects/ROOT-6.34.02/src/ROOT/6.34.02/core/meta/src/TDataMember.cxx:499
#9  0x00007ffff6cd84a6 in Cppyy::GetDatamemberOffset (scope=17, idata=0)
    at /build/jenkins/workspace/lcg_release_pipeline/build/projects/ROOT-6.34.02/src/ROOT/6.34.02/bindings/pyroot/cppyy/cppyy-backend/clingwrapper/src/clingwrapper.cxx:2110

The problem seems to be in TClingDataMemberInfo::Offset:

      // The memory leak for `EnumConstantDecl` was fixed in:
      // https://github.com/llvm/llvm-project/pull/78311
      // We were relying on the leak to provide the address for EnumConstantDecl.
      // Now store the data value as a member instead.
      fEnumValue = ECD->getInitVal().getExtValue();

APSInt::getExtValue returns the value of the arbitrary-precision integer as a (signed) int64_t, and it trips this assertion if the value is out of range. Offset() needs to be a bit more careful about retrieving the value.

Now, of course writing an enum like this is not the preferred way to write an integral constant in contemporary C++, and in fact i could alter the ATLAS class that prompted this report to not use an enum. But regardless, we shouldn't be crashing.

Reproducer

test.py

code = """
struct Foo
{
  enum E {
    BIG = ((unsigned long long)1)<<63
  };
};
"""

import ROOT
ROOT.gInterpreter.Declare (code)

f = ROOT.Foo()

On lxplus:

$ . /cvmfs/sft.cern.ch/lcg/views/LCG_107/x86_64-el9-gcc13-dbg/setup.sh
$ python -i test.py

python: /build/jenkins/workspace/lcg_release_pipeline/build/projects/ROOT-6.34.02/src/ROOT/6.34.02/interpreter/llvm-project/llvm/include/llvm/ADT/APSInt.h:99: int64_t llvm::APSInt::getExtValue() const: Assertion `isRepresentableByInt64() && "Too many bits for int64_t"' failed.
 *** Break *** abort

ROOT version

   ------------------------------------------------------------------
  | Welcome to ROOT 6.34.02                        https://root.cern |
  | (c) 1995-2024, The ROOT Team; conception: R. Brun, F. Rademakers |
  | Built for linuxx8664gcc on Jan 31 2025, 14:46:24                 |
  | From tags/6-34-02@6-34-02                                        |
  | With g++ (GCC) 13.1.0                                            |
  | Try '.help'/'.?', '.demo', '.license', '.credits', '.quit'/'.q'  |
   ------------------------------------------------------------------

Installation method

lcg

Operating system

lxplus9

Additional context

No response

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions