This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[committed] Fix ICE on OVERLOAD in OpenMP clauses (PR c++/81154)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 21 Jun 2017 20:34:14 +0200
- Subject: [committed] Fix ICE on OVERLOAD in OpenMP clauses (PR c++/81154)
- Authentication-results: sourceware.org; auth=none
- Authentication-results: ext-mx05.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com
- Authentication-results: ext-mx05.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=jakub at redhat dot com
- Dkim-filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 8CBE72FE557
- Dmarc-filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 8CBE72FE557
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
tsubst_* ICEs when seeing an OVERLOAD that is dependent on template
arguments. But if we see an OVERLOAD in an OpenMP data sharing/mapping clause,
even when processing_template_decl we know that it won't be a variable,
so we can as well diagnose it right away, without having to wait for the
instantiation.
Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk,
queued for backports.
2017-06-21 Jakub Jelinek <jakub@redhat.com>
PR c++/81154
* semantics.c (handle_omp_array_sections_1, finish_omp_clauses):
Complain about t not being a variable if t is OVERLOAD even
when processing_template_decl.
* g++.dg/gomp/pr81154.C: New test.
--- gcc/cp/semantics.c.jj 2017-06-20 08:48:38.000000000 +0200
+++ gcc/cp/semantics.c 2017-06-21 17:47:03.281327745 +0200
@@ -4589,7 +4589,7 @@ handle_omp_array_sections_1 (tree c, tre
}
if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
{
- if (processing_template_decl)
+ if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
return NULL_TREE;
if (DECL_P (t))
error_at (OMP_CLAUSE_LOCATION (c),
@@ -6109,7 +6109,7 @@ finish_omp_clauses (tree clauses, enum c
if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL
&& (!field_ok || TREE_CODE (t) != FIELD_DECL))
{
- if (processing_template_decl)
+ if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
break;
if (DECL_P (t))
error ("%qD is not a variable in clause %qs", t,
@@ -6181,7 +6181,7 @@ finish_omp_clauses (tree clauses, enum c
&& ((ort & C_ORT_OMP_DECLARE_SIMD) != C_ORT_OMP
|| TREE_CODE (t) != FIELD_DECL))
{
- if (processing_template_decl)
+ if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
break;
if (DECL_P (t))
error ("%qD is not a variable in clause %<firstprivate%>", t);
@@ -6224,7 +6224,7 @@ finish_omp_clauses (tree clauses, enum c
&& ((ort & C_ORT_OMP_DECLARE_SIMD) != C_ORT_OMP
|| TREE_CODE (t) != FIELD_DECL))
{
- if (processing_template_decl)
+ if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
break;
if (DECL_P (t))
error ("%qD is not a variable in clause %<lastprivate%>", t);
@@ -6587,7 +6587,7 @@ finish_omp_clauses (tree clauses, enum c
}
if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
{
- if (processing_template_decl)
+ if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
break;
if (DECL_P (t))
error ("%qD is not a variable in %<aligned%> clause", t);
@@ -6669,7 +6669,7 @@ finish_omp_clauses (tree clauses, enum c
remove = true;
else if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
{
- if (processing_template_decl)
+ if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
break;
if (DECL_P (t))
error ("%qD is not a variable in %<depend%> clause", t);
@@ -6800,7 +6800,7 @@ finish_omp_clauses (tree clauses, enum c
}
if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL)
{
- if (processing_template_decl)
+ if (processing_template_decl && TREE_CODE (t) != OVERLOAD)
break;
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
&& (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
--- gcc/testsuite/g++.dg/gomp/pr81154.C.jj 2017-06-21 18:13:21.235405677 +0200
+++ gcc/testsuite/g++.dg/gomp/pr81154.C 2017-06-21 18:13:03.000000000 +0200
@@ -0,0 +1,57 @@
+// PR c++/81154
+// { dg-do compile }
+
+template <typename T>
+struct C
+{
+ int foo (T n) const
+ {
+#pragma omp parallel shared (foo) // { dg-error "is not a variable in clause" }
+ ;
+#pragma omp parallel private (foo) // { dg-error "is not a variable in clause" }
+ ;
+#pragma omp parallel firstprivate (foo) // { dg-error "is not a variable in clause" }
+ ;
+#pragma omp parallel for lastprivate (foo) // { dg-error "is not a variable in clause" }
+ for (T i = 0; i < n; i++)
+ ;
+#pragma omp parallel for linear (foo) // { dg-error "is not a variable in clause" }
+ for (T i = 0; i < n; i++)
+ ;
+#pragma omp parallel reduction (+:foo) // { dg-error "is not a variable in clause" }
+ ;
+ return 0;
+ }
+ int foo (int x, int y) { return x; }
+};
+
+struct D
+{
+ typedef int T;
+ int foo (T n) const
+ {
+#pragma omp parallel shared (foo) // { dg-error "is not a variable in clause" }
+ ;
+#pragma omp parallel private (foo) // { dg-error "is not a variable in clause" }
+ ;
+#pragma omp parallel firstprivate (foo) // { dg-error "is not a variable in clause" }
+ ;
+#pragma omp parallel for lastprivate (foo) // { dg-error "is not a variable in clause" }
+ for (T i = 0; i < n; i++)
+ ;
+#pragma omp parallel for linear (foo) // { dg-error "is not a variable in clause" }
+ for (T i = 0; i < n; i++)
+ ;
+#pragma omp parallel reduction (+:foo) // { dg-error "is not a variable in clause" }
+ ;
+ return 0;
+ }
+ int foo (int x, int y) { return x; }
+};
+
+int
+main ()
+{
+ C<int> ().foo (1);
+ D ().foo (1);
+}
Jakub