aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran
diff options
context:
space:
mode:
authorDominique d'Humieres <dominiq@lps.ens.fr>2017-12-10 20:11:18 +0100
committerDominique d'Humieres <dominiq@gcc.gnu.org>2017-12-10 20:11:18 +0100
commit9845246060ebc7f29b765d67746e481b90bc1f45 (patch)
treee0047c9906a51d84e06d2944ae385944c060896f /gcc/fortran
parentb769d06ee35e1fa51c6a1d752664c04d456c9244 (diff)
downloadgcc-9845246060ebc7f29b765d67746e481b90bc1f45.zip
gcc-9845246060ebc7f29b765d67746e481b90bc1f45.tar.gz
gcc-9845246060ebc7f29b765d67746e481b90bc1f45.tar.bz2
re PR fortran/53478 (gfortran segfaults when module name clashes with C binding name of procedure)
2017-12-10 Dominique d'Humieres <dominiq@lps.ens.fr> PR fortran/53478 * gfortran.h (gfc_find_case_gsymbol): New prototype. * symbol.c (gfc_find_case_gsymbol): New procedure, case insensistive version of gfc_find_gsymbol. * resolve.c (resolve_common_blocks): Use it. Replace %s with %qs where needed. * gfortran.dg/binding_label_tests_4.f03: Update dg-error. * gfortran.dg/binding_label_tests_6.f03: Likewise. * gfortran.dg/binding_label_tests_7.f03: Likewise. * gfortran.dg/binding_label_tests_8.f03: Likewise. * gfortran.dg/binding_label_tests_10_main.f03: Likewise. * gfortran.dg/binding_label_tests_11_main.f03: Likewise. * gfortran.dg/binding_label_tests_13_main.f03: Likewise. * gfortran.dg/test_common_binding_labels_3_main.f03: Likewise. * gfortran.dg/binding_label_tests_29.f90: New test. From-SVN: r255530
Diffstat (limited to 'gcc/fortran')
-rw-r--r--gcc/fortran/ChangeLog9
-rw-r--r--gcc/fortran/gfortran.h1
-rw-r--r--gcc/fortran/resolve.c12
-rw-r--r--gcc/fortran/symbol.c23
4 files changed, 39 insertions, 6 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index c98c64b..a668e12 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,12 @@
+2017-12-10 Dominique d'Humieres <dominiq@lps.ens.fr>
+
+ PR fortran/53478
+ * gfortran.h (gfc_find_case_gsymbol): New prototype.
+ * symbol.c (gfc_find_case_gsymbol): New procedure, case
+ insensistive version of gfc_find_gsymbol.
+ * resolve.c (resolve_common_blocks): Use it.
+ Replace %s with %qs where needed.
+
2017-12-09 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/82934
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 97db5b0..c5e62d7 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -3035,6 +3035,7 @@ void gfc_free_dt_list (void);
gfc_gsymbol *gfc_get_gsymbol (const char *);
gfc_gsymbol *gfc_find_gsymbol (gfc_gsymbol *, const char *);
+gfc_gsymbol *gfc_find_case_gsymbol (gfc_gsymbol *, const char *);
gfc_typebound_proc* gfc_get_typebound_proc (gfc_typebound_proc*);
gfc_symbol* gfc_get_derived_super_type (gfc_symbol*);
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 041ee0d..f819b71 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -1056,7 +1056,7 @@ resolve_common_blocks (gfc_symtree *common_root)
common_root->n.common->binding_label);
if (gsym && gsym->type != GSYM_COMMON)
{
- gfc_error ("COMMON block at %L with binding label %s uses the same "
+ gfc_error ("COMMON block at %L with binding label %qs uses the same "
"global identifier as entity at %L",
&common_root->n.common->where,
common_root->n.common->binding_label, &gsym->where);
@@ -11542,7 +11542,7 @@ gfc_verify_binding_labels (gfc_symbol *sym)
|| sym->attr.flavor == FL_DERIVED || !sym->binding_label)
return;
- gsym = gfc_find_gsymbol (gfc_gsym_root, sym->binding_label);
+ gsym = gfc_find_case_gsymbol (gfc_gsym_root, sym->binding_label);
if (sym->module)
module = sym->module;
@@ -11578,7 +11578,7 @@ gfc_verify_binding_labels (gfc_symbol *sym)
if (sym->attr.flavor == FL_VARIABLE && gsym->type != GSYM_UNKNOWN)
{
- gfc_error ("Variable %s with binding label %s at %L uses the same global "
+ gfc_error ("Variable %qs with binding label %qs at %L uses the same global "
"identifier as entity at %L", sym->name,
sym->binding_label, &sym->declared_at, &gsym->where);
/* Clear the binding label to prevent checking multiple times. */
@@ -11591,8 +11591,8 @@ gfc_verify_binding_labels (gfc_symbol *sym)
{
/* This can only happen if the variable is defined in a module - if it
isn't the same module, reject it. */
- gfc_error ("Variable %s from module %s with binding label %s at %L uses "
- "the same global identifier as entity at %L from module %s",
+ gfc_error ("Variable %qs from module %qs with binding label %qs at %L "
+ "uses the same global identifier as entity at %L from module %qs",
sym->name, module, sym->binding_label,
&sym->declared_at, &gsym->where, gsym->mod_name);
sym->binding_label = NULL;
@@ -11608,7 +11608,7 @@ gfc_verify_binding_labels (gfc_symbol *sym)
/* Print an error if the procedure is defined multiple times; we have to
exclude references to the same procedure via module association or
multiple checks for the same procedure. */
- gfc_error ("Procedure %s with binding label %s at %L uses the same "
+ gfc_error ("Procedure %qs with binding label %qs at %L uses the same "
"global identifier as entity at %L", sym->name,
sym->binding_label, &sym->declared_at, &gsym->where);
sym->binding_label = NULL;
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index 11b6f60..dc1688a 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -4291,6 +4291,29 @@ gfc_find_gsymbol (gfc_gsymbol *symbol, const char *name)
}
+/* Case insensitive search a tree for the global symbol. */
+
+gfc_gsymbol *
+gfc_find_case_gsymbol (gfc_gsymbol *symbol, const char *name)
+{
+ int c;
+
+ if (symbol == NULL)
+ return NULL;
+
+ while (symbol)
+ {
+ c = strcasecmp (name, symbol->name);
+ if (!c)
+ return symbol;
+
+ symbol = (c < 0) ? symbol->left : symbol->right;
+ }
+
+ return NULL;
+}
+
+
/* Compare two global symbols. Used for managing the BB tree. */
static int