diff options
author | Dominique d'Humieres <dominiq@lps.ens.fr> | 2017-12-10 20:11:18 +0100 |
---|---|---|
committer | Dominique d'Humieres <dominiq@gcc.gnu.org> | 2017-12-10 20:11:18 +0100 |
commit | 9845246060ebc7f29b765d67746e481b90bc1f45 (patch) | |
tree | e0047c9906a51d84e06d2944ae385944c060896f /gcc/fortran | |
parent | b769d06ee35e1fa51c6a1d752664c04d456c9244 (diff) | |
download | gcc-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/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/fortran/gfortran.h | 1 | ||||
-rw-r--r-- | gcc/fortran/resolve.c | 12 | ||||
-rw-r--r-- | gcc/fortran/symbol.c | 23 |
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 |