The lowering for firstprivate uses the pointer size rather than the size
of the referenced object when passed an optional argument.  This patch
detects optional arguments as a special case and treats them as reference types.

        gcc/
        * omp-general.c (omp_is_optional_argument): New.
        * omp-general.h (omp_is_optional_argument): New.
        * omp-low.c (lower_omp_target): Use size of referenced object when
        optional argument used as argument to firstprivate.
---
 gcc/ChangeLog.openacc | 7 +++++++
 gcc/omp-general.c     | 9 +++++++++
 gcc/omp-general.h     | 1 +
 gcc/omp-low.c         | 3 ++-
 4 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/gcc/ChangeLog.openacc b/gcc/ChangeLog.openacc
index 744cf02..04d18c0 100644
--- a/gcc/ChangeLog.openacc
+++ b/gcc/ChangeLog.openacc
@@ -1,3 +1,10 @@
+2019-01-30  Kwok Cheung Yeung  <k...@codesourcery.com>
+
+       * omp-general.c (omp_is_optional_argument): New.
+       * omp-general.h (omp_is_optional_argument): New.
+       * omp-low.c (lower_omp_target): Use size of referenced object when
+       optional argument used as argument to firstprivate.
+
 2019-01-30  Thomas Schwinge  <tho...@codesourcery.com>

        * doc/invoke.texi (C Language Options): List "-fopenacc-dim".
diff --git a/gcc/omp-general.c b/gcc/omp-general.c
index 1897f00..dd37c46 100644
--- a/gcc/omp-general.c
+++ b/gcc/omp-general.c
@@ -46,6 +46,15 @@ omp_find_clause (tree clauses, enum omp_clause_code kind)
   return NULL_TREE;
 }

+/* Return true if DECL is a Fortran optional argument.  */
+
+bool
+omp_is_optional_argument (tree decl)
+{
+  return TREE_CODE (decl) == PARM_DECL && DECL_BY_REFERENCE (decl)
+        && TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE;
+}
+
 /* Return true if DECL is a reference type.  */

 bool
diff --git a/gcc/omp-general.h b/gcc/omp-general.h
index b704427..c5e7446 100644
--- a/gcc/omp-general.h
+++ b/gcc/omp-general.h
@@ -72,6 +72,7 @@ struct omp_for_data
 #define OACC_FN_ATTRIB "oacc function"

 extern tree omp_find_clause (tree clauses, enum omp_clause_code kind);
+extern bool omp_is_optional_argument (tree decl);
 extern bool omp_is_reference (tree decl);
extern void omp_adjust_for_condition (location_t loc, enum tree_code *cond_code,
                                      tree *n2);
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index f48002e..ef71704 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -8749,7 +8749,8 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
                else
                  {
                    s = TREE_TYPE (ovar);
-                   if (TREE_CODE (s) == REFERENCE_TYPE)
+                   if (TREE_CODE (s) == REFERENCE_TYPE
+                       || omp_is_optional_argument (ovar))
                      s = TREE_TYPE (s);
                    s = TYPE_SIZE_UNIT (s);
                  }
--
2.8.1

Reply via email to