Bug 107041 - [13/14 Regression] C '-Wenum-int-mismatch' diagnostic for OpenACC 'acc_on_device'
Summary: [13/14 Regression] C '-Wenum-int-mismatch' diagnostic for OpenACC 'acc_on_dev...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libgomp (show other bugs)
Version: 13.0
: P3 normal
Target Milestone: 13.2
Assignee: Jakub Jelinek
URL:
Keywords: diagnostic, openacc
Depends on:
Blocks:
 
Reported: 2022-09-26 13:42 UTC by Thomas Schwinge
Modified: 2023-04-26 08:38 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2023-04-18 00:00:00


Attachments
gcc14-pr107041.patch (927 bytes, patch)
2023-04-18 08:39 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas Schwinge 2022-09-26 13:42:27 UTC
Clean for C++:

    $ printf '#include <openacc.h>\nint foo(){ return acc_on_device(acc_device_host); }\n' | build-gcc/gcc/xgcc -Bbuild-gcc/gcc -Isource-gcc/libgomp -x c++ - -fopenacc -S -Wall

..., but not anymore for C:

    $ printf '#include <openacc.h>\nint foo(){ return acc_on_device(acc_device_host); }\n' | build-gcc/gcc/xgcc -Bbuild-gcc/gcc -Isource-gcc/libgomp -x c - -fopenacc -S -Wall
    In file included from <stdin>:1:
    source-gcc/libgomp/openacc.h:103:5: warning: conflicting types for ‘acc_on_device’ due to enum/integer mismatch; have ‘int(acc_device_t)’ [-Wenum-int-mismatch]
      103 | int acc_on_device (acc_device_t __arg) __GOACC_NOTHROW;
          |     ^~~~~~~~~~~~~

That's commit r13-627-g7da9a089608b0ca09683332ce014fb6184842724 "c: Implement new -Wenum-int-mismatch warning [PR105131]".

This causes excess errors (only!) for 'libgomp.oacc-c/../libgomp.oacc-c-c++-common/host_data-1.c' (when its prerequisites are met); that's one of the few libgomp test cases where '-Wall' is in effect.  (I'd "complained" about lack of '-Wall' testing before.)

OpenACC 'acc_on_device' is implemented as follows:

    libgomp/openacc.h-#ifdef __cplusplus
    libgomp/openacc.h:int acc_on_device (int __arg) __GOACC_NOTHROW;
    libgomp/openacc.h-#else
    libgomp/openacc.h:int acc_on_device (acc_device_t __arg) __GOACC_NOTHROW;
    libgomp/openacc.h-#endif

    libgomp/openacc.h-#ifdef __cplusplus
    libgomp/openacc.h-[...]
    libgomp/openacc.h-
    libgomp/openacc.h-/* Forwarding function with correctly typed arg.  */
    libgomp/openacc.h-
    libgomp/openacc.h-#pragma acc routine seq
    libgomp/openacc.h:inline int acc_on_device (acc_device_t __arg) __GOACC_NOTHROW
    libgomp/openacc.h-{
    libgomp/openacc.h:  return acc_on_device ((int) __arg);
    libgomp/openacc.h-}
    libgomp/openacc.h-#endif

    gcc/omp-builtins.def:DEF_GOACC_BUILTIN_COMPILER (BUILT_IN_ACC_ON_DEVICE, "acc_on_device",
    gcc/omp-builtins.def-                            BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)

    libgomp/oacc-init.c:/* For -O and higher, the compiler always attempts to expand acc_on_device, but
    libgomp/oacc-init.c-   if the user disables the builtin, or calls it via a pointer, we'll need this
    libgomp/oacc-init.c-   version.
    libgomp/oacc-init.c-
    libgomp/oacc-init.c-   Compile this with optimization, so that the compiler expands
    libgomp/oacc-init.c-   this, rather than generating infinitely recursive code.
    libgomp/oacc-init.c-
    libgomp/oacc-init.c:   The function just forwards its argument to __builtin_acc_on_device.  It does
    libgomp/oacc-init.c-   not verify that the argument is a valid acc_device_t enumeration value.  */
    libgomp/oacc-init.c-
    libgomp/oacc-init.c-int __attribute__ ((__optimize__ ("O2")))
    libgomp/oacc-init.c:acc_on_device (acc_device_t dev)
    libgomp/oacc-init.c-{
    libgomp/oacc-init.c:  return __builtin_acc_on_device (dev);
    libgomp/oacc-init.c-}
    libgomp/oacc-init.c-
    libgomp/oacc-init.c:ialias (acc_on_device)

If I remember correctly, the reason for the "strange" prototyping/forwarding is that GCC builtins don't allow for 'enum' arguments?  (I may be misremembering.)

---

Maybe a fix for this would fall out of Tom's patch for PR82391 "[openacc] acc_on_device not folded at -O0"?  (I've paged out all state of that one, unfortunately.)
Comment 1 Richard Biener 2022-12-22 14:35:22 UTC
Using a specific builtin enum type in builtins is indeed difficult.
Comment 2 Richard Biener 2023-03-27 13:55:56 UTC
Note you can have a custom type instead of BT_FN_INT_INT, you could use
a DEF_PRIMITIVE_TYPE and have a global variable initialized where we
initialize builtins for it.
Comment 3 Jakub Jelinek 2023-04-17 15:23:07 UTC
If this is really just because it is a builtin, I think another possibility would be
make it BT_FN_INT_VAR instead of BT_FN_INT_INT and verify it has just one argument which
is either int or the particularly named enum say in builtins.cc folding or so.
Comment 4 Jakub Jelinek 2023-04-17 17:36:29 UTC
I think this is less important as it normally should trigger only with -Wall -Wsystem-headers.

Anyway, one fix could be e.g.
--- gcc/omp-builtins.def.jj	2023-04-17 19:11:55.065865863 +0200
+++ gcc/omp-builtins.def	2023-04-17 19:14:45.433406545 +0200
@@ -52,7 +52,7 @@ DEF_GOACC_BUILTIN (BUILT_IN_GOACC_DECLAR
 		   BT_FN_VOID_INT_SIZE_PTR_PTR_PTR, ATTR_NOTHROW_LIST)
 
 DEF_GOACC_BUILTIN_COMPILER (BUILT_IN_ACC_ON_DEVICE, "acc_on_device",
-			    BT_FN_INT_INT, ATTR_CONST_NOTHROW_LEAF_LIST)
+			    BT_FN_INT_VAR, ATTR_CONST_NOTHROW_LEAF_LIST)
 
 DEF_GOACC_BUILTIN_ONLY (BUILT_IN_GOACC_PARLEVEL_ID, "goacc_parlevel_id",
 			BT_FN_INT_INT, ATTR_NOTHROW_LEAF_LIST)
--- gcc/c-family/c-common.cc.jj	2023-03-28 17:47:46.769970692 +0200
+++ gcc/c-family/c-common.cc	2023-04-17 19:28:31.037488778 +0200
@@ -6493,6 +6493,25 @@ check_builtin_function_arguments (locati
 	}
       return false;
 
+    case BUILT_IN_ACC_ON_DEVICE:
+      if (builtin_function_validate_nargs (loc, fndecl, nargs, 1))
+	{
+	  if (TREE_CODE (TREE_TYPE (args[0])) != INTEGER_TYPE
+	      && (TREE_CODE (TREE_TYPE (args[0])) != ENUMERAL_TYPE
+		  || (TREE_CODE (TREE_TYPE (TREE_TYPE (args[0])))
+		      != INTEGER_TYPE)
+		  || (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (args[0])))
+		      != integer_type_node)))
+	    {
+	      error_at (ARG_LOCATION (0), "argument %u in call to function "
+			"%qE does not have integer or enumerated type",
+			1, fndecl);
+	      return false;
+	    }
+	  return true;
+	}
+      return false;
+
     default:
       return true;
     }
--- gcc/fortran/types.def.jj	2023-04-17 19:11:55.065865863 +0200
+++ gcc/fortran/types.def	2023-04-17 19:14:45.433406545 +0200
@@ -264,6 +264,7 @@ DEF_FUNCTION_TYPE_11 (BT_FN_VOID_OMPFN_P
 		      BT_ULONGLONG, BT_ULONGLONG, BT_ULONGLONG)
 
 DEF_FUNCTION_TYPE_VAR_0 (BT_FN_VOID_VAR, BT_VOID)
+DEF_FUNCTION_TYPE_VAR_0 (BT_FN_INT_VAR, BT_INT)
 
 DEF_FUNCTION_TYPE_VAR_1 (BT_FN_VOID_LONG_VAR,
 			 BT_VOID, BT_LONG)
plus testsuite changes.
But that would break
#include <openacc.h>
struct S { operator acc_device_t () { return acc_device_none; } };

int
foo ()
{
  S s;
  return acc_on_device (s);
}
Another option would be just disable the warning for this particular builtin where the warning is reported.
Comment 5 Jakub Jelinek 2023-04-18 08:39:27 UTC
Created attachment 54879 [details]
gcc14-pr107041.patch

Untested fix.
Comment 6 GCC Commits 2023-04-20 17:30:54 UTC
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:3d7ab53d6c59499624aa41c8dea0664976820b3b

commit r14-120-g3d7ab53d6c59499624aa41c8dea0664976820b3b
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Thu Apr 20 19:26:17 2023 +0200

    c: Avoid -Wenum-int-mismatch warning for redeclaration of builtin acc_on_device [PR107041]
    
    The new -Wenum-int-mismatch warning triggers with -Wsystem-headers in
    <openacc.h>, for obvious reasons the builtin acc_on_device uses int
    type argument rather than enum which isn't defined yet when the builtin
    is created, while the OpenACC spec requires it to have acc_device_t
    enum argument.  The header makes sure it has int underlying type by using
    negative and __INT_MAX__ enumerators.
    
    I've tried to make the builtin typegeneric or just varargs, but that
    changes behavior e.g. when one calls it with some C++ class which has
    cast operator to acc_device_t, so the following patch instead disables
    the warning for this builtin.
    
    2023-04-20  Jakub Jelinek  <jakub@redhat.com>
    
            PR c/107041
            * c-decl.cc (diagnose_mismatched_decls): Avoid -Wenum-int-mismatch
            warning on acc_on_device declaration.
    
            * gcc.dg/goacc/pr107041.c: New test.
Comment 7 Richard Biener 2023-04-26 06:56:46 UTC
GCC 13.1 is being released, retargeting bugs to GCC 13.2.
Comment 8 GCC Commits 2023-04-26 08:37:44 UTC
The releases/gcc-13 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:f8646b8dcb18721e776c39117f62aee7ee571f21

commit r13-7246-gf8646b8dcb18721e776c39117f62aee7ee571f21
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Thu Apr 20 19:26:17 2023 +0200

    c: Avoid -Wenum-int-mismatch warning for redeclaration of builtin acc_on_device [PR107041]
    
    The new -Wenum-int-mismatch warning triggers with -Wsystem-headers in
    <openacc.h>, for obvious reasons the builtin acc_on_device uses int
    type argument rather than enum which isn't defined yet when the builtin
    is created, while the OpenACC spec requires it to have acc_device_t
    enum argument.  The header makes sure it has int underlying type by using
    negative and __INT_MAX__ enumerators.
    
    I've tried to make the builtin typegeneric or just varargs, but that
    changes behavior e.g. when one calls it with some C++ class which has
    cast operator to acc_device_t, so the following patch instead disables
    the warning for this builtin.
    
    2023-04-20  Jakub Jelinek  <jakub@redhat.com>
    
            PR c/107041
            * c-decl.cc (diagnose_mismatched_decls): Avoid -Wenum-int-mismatch
            warning on acc_on_device declaration.
    
            * gcc.dg/goacc/pr107041.c: New test.
    
    (cherry picked from commit 3d7ab53d6c59499624aa41c8dea0664976820b3b)
Comment 9 Jakub Jelinek 2023-04-26 08:38:42 UTC
Fixed.