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