https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119692
Bug ID: 119692 Summary: C++ 'typeinfo', 'vtable' vs. OpenACC, OpenMP 'target' offloading Product: gcc Version: 15.0 Status: UNCONFIRMED Keywords: openacc, openmp Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: tschwinge at gcc dot gnu.org CC: burnus at gcc dot gnu.org, jakub at gcc dot gnu.org Target Milestone: --- Created attachment 61052 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=61052&action=edit 'pr.C' The attached 'pr.C' is meant to execute and terminate normally, but with '-fopenmp' and offload device available, we get: Thread 1 "a.out" received signal SIGSEGV, Segmentation fault. 0x00007ffff5e87655 in ?? () from /lib/x86_64-linux-gnu/libcuda.so.1 (gdb) bt [...] #8 0x00007ffff602a61e in ?? () from /lib/x86_64-linux-gnu/libcuda.so.1 #9 0x00007ffff79a398c in GOMP_OFFLOAD_dev2host (ord=<optimized out>, dst=0x402020 <typeinfo for C2>, src=0x7fffcb600018, n=24) at ../../../source-gcc/libgomp/plugin/plugin-nvptx.c:2073 #10 0x00007ffff7c2db38 in gomp_device_copy (devicep=0x4faa40, copy_func=<optimized out>, dst=0x7ffff7c442c9 "host", dstaddr=0x402020 <typeinfo for C2>, src=0x7ffff7c442e0 "dev", srcaddr=0x7fffcb600018, size=24) at ../../../source-gcc/libgomp/target.c:247 #11 gomp_copy_dev2host (devicep=0x4faa40, aq=0x0, h=0x402020 <typeinfo for C2>, d=0x7fffcb600018, sz=24) at ../../../source-gcc/libgomp/target.c:461 #12 gomp_unmap_vars_internal (tgt=0xb6ace0, do_copyfrom=true, refcount_set=0x7fffffffd738, aq=0x0) at ../../../source-gcc/libgomp/target.c:2089 #13 gomp_unmap_vars (tgt=tgt@entry=0xb6ace0, refcount_set=refcount_set@entry=0x7fffffffd738, do_copyfrom=true) at ../../../source-gcc/libgomp/target.c:2129 #14 0x00007ffff7c2f80f in GOMP_target_ext (device=<optimized out>, fn=<optimized out>, mapnum=<optimized out>, hostaddrs=<optimized out>, sizes=<optimized out>, kinds=<optimized out>, flags=<optimized out>, depend=<optimized out>, args=<optimized out>) at ../../../source-gcc/libgomp/target.c:3307 #15 0x00000000004011e2 in main () at [...]/pr.C:13 Per '-fdump-tree-gimple', we've got : #pragma omp target [...] map(tofrom:_ZTI2C2 [len: 24] [runtime_implicit]) map(tofrom:_ZTI2C1 [len: 16] [runtime_implicit]) map(tofrom:_ZTV2C1 [len: 24] [runtime_implicit]) ..., which are: $ c++filt _ZTI2C2 _ZTI2C1 _ZTV2C1 typeinfo for C2 typeinfo for C1 vtable for C1 ..., and per '*.s', they're in '.rodata'. (..., and the offloading machinery wouldn't have any business modifying these, anyway?) Why do we 'map' these 'tofrom' -- and how to fix this? I suppose we should 'firstprivate' these, or at least only 'GOMP_MAP_TO'? Would this be done in the gimplifier (via 'GOVD_FIRSTPRIVATE', or 'GOVD_MAP_TO_ONLY'?), or in the C++ front end (via langhook?)? (Have not yet looked, but supposedly Fortran would do some similar handling for its array descriptors?) With OpenMP 'defaultmap(none)': [...]/pr.C: In function ‘int main()’: [...]/pr.C:16:8: error: ‘_ZTV2C1’ not specified in enclosing ‘target’ [...]/pr.C:13:9: note: enclosing ‘target’ [...]/pr.C:22:18: error: ‘_ZTI2C2’ not specified in enclosing ‘target’ [...]/pr.C:13:9: note: enclosing ‘target’ [...]/pr.C:22:18: error: ‘_ZTI2C1’ not specified in enclosing ‘target’ [...]/pr.C:13:9: note: enclosing ‘target’ Should 'defaultmap(none)' really report compiler-internal variables? With OpenMP 'defaultmap(firstprivate)': #pragma omp target [...] firstprivate(_ZTI2C2) firstprivate(_ZTI2C1) firstprivate(_ZTV2C1) ..., and we get successful execution with offload device. Similar for '-fopenacc': #pragma omp target oacc_serial map(tofrom:_ZTI2C2 [len: 24]) map(tofrom:_ZTI2C1 [len: 16]) map(tofrom:_ZTV2C1 [len: 24]) ..., but OpenACC 'default(none)' doesn't report these -- should it, like OpenMP 'defaultmap(none)'? That's probably because of 'DECL_ARTIFICIAL' handling in 'oacc_default_clause'. (There's no OpenACC 'default(firstprivate)'.)