diff options
author | jb <jb@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-01-29 17:19:32 +0000 |
---|---|---|
committer | jb <jb@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-01-29 17:19:32 +0000 |
commit | 7b2060ba65acd2fdcbf0dedd5ad0a268b2028b51 (patch) | |
tree | 9cf48d558f50c1053b18c202c9c36d7a8a46c9f8 /gcc/fortran/match.c | |
parent | 3e6bf5fe04413ffdcf981bf74684309cb7cf6800 (diff) | |
download | gcc-7b2060ba65acd2fdcbf0dedd5ad0a268b2028b51.tar.gz |
PR 51808 Support arbitrarily long bind(C) binding labels.
2012-01-29 Janne Blomqvist <jb@gcc.gnu.org>
PR fortran/51808
* decl.c (set_binding_label): Move prototype from match.h to here.
(curr_binding_label): Make a pointer rather than static array.
(build_sym): Check sym->binding_label pointer rather than array,
update set_binding_label call, handle curr_binding_label changes.
(set_binding_label): Handle new curr_binding_label, dest_label
double ptr, and sym->binding_label.
(verify_bind_c_sym): Handle sym->binding_label being a pointer.
(set_verify_bind_c_sym): Check sym->binding_label pointer rather
than array, update set_binding_label call.
(gfc_match_bind_c_stmt): Handle curr_binding_label change.
(match_procedure_decl): Update set_binding_label call.
(gfc_match_bind_c): Change binding_label to pointer, update
gfc_match_name_C call.
* gfortran.h (GFC_MAX_BINDING_LABEL_LEN): Remove macro.
(gfc_symbol): Make binding_label a pointer.
(gfc_common_head): Likewise.
* match.c (gfc_match_name_C): Heap allocate bind(C) name.
* match.h (gfc_match_name_C): Change prototype argument.
(set_binding_label): Move prototype to decl.c.
* module.c (struct pointer_info): Make binding_label a pointer.
(free_pi_tree): Free unused binding_label.
(mio_read_string): New function.
(mio_write_string): New function.
(load_commons): Redo reading of binding_label.
(read_module): Likewise.
(write_common_0): Change to write empty string instead of name if
no binding_label.
(write_blank_common): Write empty string for binding label.
(write_symbol): Change to write empty string instead of name if no
binding_label.
* resolve.c (gfc_iso_c_func_interface): Don't set binding_label.
(set_name_and_label): Make binding_label double pointer, use
asprintf.
(gfc_iso_c_sub_interface): Make binding_label a pointer.
(resolve_bind_c_comms): Handle cases if
gfc_common_head->binding_label is NULL.
(gfc_verify_binding_labels): sym->binding_label is a pointer.
* symbol.c (gfc_free_symbol): Free binding_label.
(gfc_new_symbol): Rely on XCNEW zero init for binding_label.
(gen_special_c_interop_ptr): Don't set binding label.
(generate_isocbinding_symbol): Insert binding_label into symbol
table.
(get_iso_c_sym): Use pointer assignment instead of strcpy.
* trans-common.c (gfc_sym_mangled_common_id): Handle
com->binding_label being a pointer.
* trans-decl.c (gfc_sym_mangled_identifier): Handle
sym->binding_label being a pointer.
(gfc_sym_mangled_function_id): Likewise.
testsuite ChangeLog
2012-01-29 Janne Blomqvist <jb@gcc.gnu.org>
PR fortran/51808
* gfortran.dg/module_md5_1.f90: Update MD5 sum.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@183677 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/fortran/match.c')
-rw-r--r-- | gcc/fortran/match.c | 47 |
1 files changed, 23 insertions, 24 deletions
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c index 05853081173..3024cc7b9c9 100644 --- a/gcc/fortran/match.c +++ b/gcc/fortran/match.c @@ -1,6 +1,6 @@ /* Matching subroutines in all sizes, shapes and colors. Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, - 2009, 2010, 2011 + 2009, 2010, 2011, 2012 Free Software Foundation, Inc. Contributed by Andy Vaught @@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "gfortran.h" #include "match.h" #include "parse.h" +#include "tree.h" int gfc_matching_ptr_assignment = 0; int gfc_matching_procptr_assignment = 0; @@ -571,22 +572,22 @@ gfc_match_name (char *buffer) /* Match a valid name for C, which is almost the same as for Fortran, except that you can start with an underscore, etc.. It could have been done by modifying the gfc_match_name, but this way other - things C allows can be added, such as no limits on the length. - Right now, the length is limited to the same thing as Fortran.. + things C allows can be done, such as no limits on the length. Also, by rewriting it, we use the gfc_next_char_C() to prevent the input characters from being automatically lower cased, since C is case sensitive. The parameter, buffer, is used to return the name - that is matched. Return MATCH_ERROR if the name is too long - (though this is a self-imposed limit), MATCH_NO if what we're - seeing isn't a name, and MATCH_YES if we successfully match a C - name. */ + that is matched. Return MATCH_ERROR if the name is not a valid C + name, MATCH_NO if what we're seeing isn't a name, and MATCH_YES if + we successfully match a C name. */ match -gfc_match_name_C (char *buffer) +gfc_match_name_C (char **buffer) { locus old_loc; - int i = 0; + size_t i = 0; gfc_char_t c; + char* buf; + size_t cursz = 16; old_loc = gfc_current_locus; gfc_gobble_whitespace (); @@ -600,7 +601,6 @@ gfc_match_name_C (char *buffer) symbol name, all lowercase. */ if (c == '"' || c == '\'') { - buffer[0] = '\0'; gfc_current_locus = old_loc; return MATCH_YES; } @@ -611,24 +611,19 @@ gfc_match_name_C (char *buffer) return MATCH_ERROR; } + buf = XNEWVEC (char, cursz); /* Continue to read valid variable name characters. */ do { gcc_assert (gfc_wide_fits_in_byte (c)); - buffer[i++] = (unsigned char) c; - - /* C does not define a maximum length of variable names, to my - knowledge, but the compiler typically places a limit on them. - For now, i'll use the same as the fortran limit for simplicity, - but this may need to be changed to a dynamic buffer that can - be realloc'ed here if necessary, or more likely, a larger - upper-bound set. */ - if (i > gfc_option.max_identifier_length) - { - gfc_error ("Name at %C is too long"); - return MATCH_ERROR; - } + buf[i++] = (unsigned char) c; + + if (i >= cursz) + { + cursz *= 2; + buf = XRESIZEVEC (char, buf, cursz); + } old_loc = gfc_current_locus; @@ -636,7 +631,11 @@ gfc_match_name_C (char *buffer) c = gfc_next_char_literal (INSTRING_WARN); } while (ISALNUM (c) || c == '_'); - buffer[i] = '\0'; + /* The binding label will be needed later anyway, so just insert it + into the symbol table. */ + buf[i] = '\0'; + *buffer = IDENTIFIER_POINTER (get_identifier (buf)); + XDELETEVEC (buf); gfc_current_locus = old_loc; /* See if we stopped because of whitespace. */ |