https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127830

            Bug ID: 127830
           Summary: [OpenMP] need_device_ptr doesn't handle dependent
                    types
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: openmp, rejects-valid
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gabravier at gmail dot com
  Target Milestone: ---

#include <type_traits>

template <class T> struct P { using pointer = T *; };

template <class T> void v2 (typename P<T>::pointer x);
#pragma omp declare variant (v2<T>) match (construct={dispatch}) adjust_args
(need_device_ptr: x)
template <class T> void b2 (typename P<T>::pointer x);

template <class T> void v3 (std::add_pointer_t<T> x);
#pragma omp declare variant (v3<T>) match (construct={dispatch}) adjust_args
(need_device_ptr: x)
template <class T> void b3 (std::add_pointer_t<T> x);

My reading of the OpenMP is that this code is valid (it doesn't appear to have
any issues with dependent types as a general matter, and e.g. ยง15.5.2.1 "in the
declaration of the function variant" would seem to imply that it has to be
checked post-resolution of dependent types since the declaration doesn't exist
until template instantiation), yet GCC (with -fopenmp) complains:

<source>:6:96: error: 'x' is not a C pointer
    6 | #pragma omp declare variant (v2<T>) match (construct={dispatch})
adjust_args (need_device_ptr: x)
      |                                                                        
                       ^
<source>:10:96: error: 'x' is not a C pointer
   10 | #pragma omp declare variant (v3<T>) match (construct={dispatch})
adjust_args (need_device_ptr: x)
      |                                                                        
                       ^

...this reproduces on trunk, 16 and 15 (14 and below do not implement
dispatch).

This code seems to be at fault:

                      if (strcmp (p, "need_device_ptr") == 0)
                        {
                          bool is_ptr_or_template
                            = TEMPLATE_PARM_P (TREE_TYPE (arg))
                              || POINTER_TYPE_P (TREE_TYPE (arg));
                          if (!is_ptr_or_template)
                            {
                              error_at (arg_loc, "%qD is not a C pointer",
                                        decl);
                              continue;
                            }
                        }

...I assume it should allow dependent types, and then later do the check
properly when the type is actually resolved.

Reply via email to