Le 02/10/2015 18:44, Steve Kargl a écrit :
On Fri, Oct 02, 2015 at 11:28:06AM +0200, Mikael Morin wrote:
Le 01/10/2015 18:30, Steve Kargl a écrit :
The call-stmt in the code is the start of an execution-construct
A common-stmt is not allowed in an execution-construct. At
least, that's how I intepret the BNF in 2.1 of F2008.
The error message appears too soon, before we finish parsing the common
statement. If it's delayed, as with the following additional patch, the
common statements is properly rejected:
common_24.f:10:72:
COMMON /FMCOM / XX(80 000 000) ! { dg-error "conflicts with
COMMON" }
1
Error: Unexpected COMMON statement at (1)
common_24.f:8:72:
Error: PROCEDURE attribute conflicts with COMMON attribute in ???xx??? at (1)
This needs a little more polishing (location missing in the second error
message), then let's see how the testsuite likes it.
While I prefer the first error message above, if it requires
too much polish, then at least commit your first patch to cure
the ICE. We can worry about polish later.
I have finally managed to find a patch that doesn't regress in the
testsuite.
The gfc_add_in_common call in gfc_match_common is delayed after the
array spec handling and without return value check, so that errors are
ignored. Another gfc_add_in_common call is necessary to report errors
again during resolution. This is patch number 2.
The error location for the second call is grabbed from the common block
struct, which is made accessible in the function by patch number 1.
No regression on x86-unknown-linux-gnu, OK for trunk?
Mikael
2015-10-02 Mikael Morin <mik...@gcc.gnu.org>
* resolve.c (resolve_common_vars): Move access to the common
block's head symbol inside the function.
(resolve_common_blocks, resolve_types): Update callers.
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 7363e06..582c3f9 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -912,9 +912,9 @@ resolve_entries (gfc_namespace *ns)
/* Resolve common variables. */
static void
-resolve_common_vars (gfc_symbol *sym, bool named_common)
+resolve_common_vars (gfc_common_head *common_block, bool named_common)
{
- gfc_symbol *csym = sym;
+ gfc_symbol *csym = common_block->head;
for (; csym; csym = csym->common_next)
{
@@ -972,7 +972,7 @@ resolve_common_blocks (gfc_symtree *common_root)
if (common_root->right)
resolve_common_blocks (common_root->right);
- resolve_common_vars (common_root->n.common->head, true);
+ resolve_common_vars (common_root->n.common, true);
/* The common name is a global name - in Fortran 2003 also if it has a
C binding name, since Fortran 2008 only the C binding name is a global
@@ -15202,7 +15202,7 @@ resolve_types (gfc_namespace *ns)
resolve_entries (ns);
- resolve_common_vars (ns->blank_common.head, false);
+ resolve_common_vars (&ns->blank_common, false);
resolve_common_blocks (ns->common_root);
resolve_contained_functions (ns);
2015-10-02 Mikael Morin <mik...@gcc.gnu.org>
PR fortran/67758
* match.c (gfc_match_common): Delay the common_block pointer
assignment after error checking.
Delay the call to gfc_add_in_common attribute after the handling
of array specs.
* resolve.c (resolve_common_vars): Call gfc_add_in_common again.
2015-10-02 Mikael Morin <mik...@gcc.gnu.org>
PR fortran/67758
* gfortran.dg/common_24.f: New.
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index 523e9b2..a63c731 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -4330,10 +4330,6 @@ gfc_match_common (void)
if (m == MATCH_NO)
goto syntax;
- /* Store a ref to the common block for error checking. */
- sym->common_block = t;
- sym->common_block->refs++;
-
/* See if we know the current common block is bind(c), and if
so, then see if we can check if the symbol is (which it'll
need to be). This can happen if the bind(c) attr stmt was
@@ -4376,8 +4372,8 @@ gfc_match_common (void)
goto cleanup;
}
- if (!gfc_add_in_common (&sym->attr, sym->name, NULL))
- goto cleanup;
+ sym->common_block = t;
+ sym->common_block->refs++;
if (tail != NULL)
tail->common_next = sym;
@@ -4416,6 +4412,10 @@ gfc_match_common (void)
}
+ /* Add the in_common attribute, but ignore the reported errors
+ if any, and continue matching. */
+ gfc_add_in_common (&sym->attr, sym->name, NULL);
+
sym->common_head = t;
/* Check to see if the symbol is already in an equivalence group.
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 582c3f9..6e61250 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -918,6 +918,12 @@ resolve_common_vars (gfc_common_head *common_block, bool named_common)
for (; csym; csym = csym->common_next)
{
+ /* gfc_add_in_common may have been called before, but the reported errors
+ have been ignored to continue parsing.
+ We do the checks again here. */
+ if (!csym->attr.use_assoc)
+ gfc_add_in_common (&csym->attr, csym->name, &common_block->where);
+
if (csym->value || csym->attr.data)
{
if (!csym->ns->is_block_data)
diff --git a/gcc/testsuite/gfortran.dg/common_24.f b/gcc/testsuite/gfortran.dg/common_24.f
new file mode 100644
index 0000000..ea37c2a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/common_24.f
@@ -0,0 +1,11 @@
+c { dg-do compile }
+c PR fortran/67758
+c
+c Check the absence of ICE after emitting the error message
+c
+c Contributed by Ilya Enkovich <ienkov...@gcc.gnu.org>
+
+ COMMON /FMCOM / X(80 000 000)
+ CALL T(XX(A))
+ COMMON /FMCOM / XX(80 000 000) ! { dg-error "Unexpected COMMON" }
+ END