aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran/decl.c')
-rw-r--r--gcc/fortran/decl.c206
1 files changed, 170 insertions, 36 deletions
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 3513d177e5e..52a98cd44ed 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -99,6 +99,11 @@ bool gfc_matching_function;
/* Set upon parsing a !GCC$ unroll n directive for use in the next loop. */
int directive_unroll = -1;
+/* Set upon parsing supported !GCC$ pragmas for use in the next loop. */
+bool directive_ivdep = false;
+bool directive_vector = false;
+bool directive_novector = false;
+
/* Map of middle-end built-ins that should be vectorized. */
hash_map<nofree_string_hash, int> *gfc_vectorized_builtins;
@@ -2644,7 +2649,7 @@ variable_decl (int elem)
then we want to set the type & bail out. */
if (flag_cray_pointer && !gfc_comp_struct (gfc_current_state ()))
{
- gfc_find_symbol (name, gfc_current_ns, 1, &sym);
+ gfc_find_symbol (name, gfc_current_ns, 0, &sym);
if (sym != NULL && sym->attr.cray_pointee)
{
m = MATCH_YES;
@@ -3991,7 +3996,6 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag)
return MATCH_YES;
}
-
m = gfc_match (" type (");
matched_type = (m == MATCH_YES);
if (matched_type)
@@ -4039,7 +4043,10 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag)
m = MATCH_YES;
if (matched_type && m == MATCH_YES && gfc_match_char (')') != MATCH_YES)
- m = MATCH_ERROR;
+ {
+ gfc_error ("Malformed type-spec at %C");
+ return MATCH_ERROR;
+ }
return m;
}
@@ -4062,8 +4069,12 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag)
&& !gfc_notify_std (GFC_STD_F2008, "TYPE with "
"intrinsic-type-spec at %C"))
return MATCH_ERROR;
+
if (matched_type && gfc_match_char (')') != MATCH_YES)
- return MATCH_ERROR;
+ {
+ gfc_error ("Malformed type-spec at %C");
+ return MATCH_ERROR;
+ }
ts->type = BT_REAL;
ts->kind = gfc_default_double_kind;
@@ -4093,7 +4104,10 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag)
return MATCH_ERROR;
if (matched_type && gfc_match_char (')') != MATCH_YES)
- return MATCH_ERROR;
+ {
+ gfc_error ("Malformed type-spec at %C");
+ return MATCH_ERROR;
+ }
ts->type = BT_COMPLEX;
ts->kind = gfc_default_double_kind;
@@ -4114,7 +4128,13 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag)
if (m == MATCH_ERROR)
return m;
- m = gfc_match_char (')');
+ gfc_gobble_whitespace ();
+ if (gfc_peek_ascii_char () != ')')
+ {
+ gfc_error ("Malformed type-spec at %C");
+ return MATCH_ERROR;
+ }
+ m = gfc_match_char (')'); /* Burn closing ')'. */
}
if (m != MATCH_YES)
@@ -4397,6 +4417,7 @@ get_kind:
gfc_next_ascii_char ();
return MATCH_YES;
}
+ gfc_error ("Malformed type-spec at %C");
return MATCH_NO;
}
}
@@ -4410,7 +4431,10 @@ get_kind:
}
if (matched_type && gfc_match_char (')') != MATCH_YES)
- return MATCH_ERROR;
+ {
+ gfc_error ("Malformed type-spec at %C");
+ return MATCH_ERROR;
+ }
/* Defer association of the KIND expression of function results
until after USE and IMPORT statements. */
@@ -6145,13 +6169,17 @@ gfc_match_prefix (gfc_typespec *ts)
found_prefix = true;
}
- if (!seen_type && ts != NULL
- && gfc_match_decl_type_spec (ts, 0) == MATCH_YES
- && gfc_match_space () == MATCH_YES)
+ if (!seen_type && ts != NULL)
{
-
- seen_type = true;
- found_prefix = true;
+ match m;
+ m = gfc_match_decl_type_spec (ts, 0);
+ if (m == MATCH_ERROR)
+ goto error;
+ if (m == MATCH_YES && gfc_match_space () == MATCH_YES)
+ {
+ seen_type = true;
+ found_prefix = true;
+ }
}
if (gfc_match ("elemental% ") == MATCH_YES)
@@ -7202,13 +7230,16 @@ gfc_match_function_decl (void)
if (sym->attr.is_bind_c == 1)
{
sym->attr.is_bind_c = 0;
- if (sym->old_symbol != NULL)
- gfc_error_now ("BIND(C) attribute at %L can only be used for "
- "variables or common blocks",
- &(sym->old_symbol->declared_at));
- else
- gfc_error_now ("BIND(C) attribute at %L can only be used for "
- "variables or common blocks", &gfc_current_locus);
+
+ if (gfc_state_stack->previous
+ && gfc_state_stack->previous->state != COMP_SUBMODULE)
+ {
+ locus loc;
+ loc = sym->old_symbol != NULL
+ ? sym->old_symbol->declared_at : gfc_current_locus;
+ gfc_error_now ("BIND(C) attribute at %L can only be used for "
+ "variables or common blocks", &loc);
+ }
}
if (found_match != MATCH_YES)
@@ -7222,6 +7253,24 @@ gfc_match_function_decl (void)
found_match = suffix_match;
}
+ /* F2018 C1550 (R1526) If MODULE appears in the prefix of a module
+ subprogram and a binding label is specified, it shall be the
+ same as the binding label specified in the corresponding module
+ procedure interface body. */
+ if (sym->attr.is_bind_c && sym->attr.module_procedure && sym->old_symbol
+ && strcmp (sym->name, sym->old_symbol->name) == 0
+ && strcmp (sym->binding_label, sym->old_symbol->binding_label) != 0)
+ {
+ const char *null = "NULL", *s1, *s2;
+ s1 = sym->binding_label;
+ if (!s1) s1 = null;
+ s2 = sym->old_symbol->binding_label;
+ if (!s2) s2 = null;
+ gfc_error ("Mismatch in BIND(C) names (%qs/%qs) at %C", s1, s2);
+ sym->refs++; /* Needed to avoid an ICE in gfc_release_symbol */
+ return MATCH_ERROR;
+ }
+
if(found_match != MATCH_YES)
m = MATCH_ERROR;
else
@@ -7460,15 +7509,15 @@ gfc_match_entry (void)
not allowed for procedures. */
if (entry->attr.is_bind_c == 1)
{
+ locus loc;
+
entry->attr.is_bind_c = 0;
- if (entry->old_symbol != NULL)
- gfc_error_now ("BIND(C) attribute at %L can only be used for "
- "variables or common blocks",
- &(entry->old_symbol->declared_at));
- else
- gfc_error_now ("BIND(C) attribute at %L can only be used for "
- "variables or common blocks", &gfc_current_locus);
- }
+
+ loc = entry->old_symbol != NULL
+ ? entry->old_symbol->declared_at : gfc_current_locus;
+ gfc_error_now ("BIND(C) attribute at %L can only be used for "
+ "variables or common blocks", &loc);
+ }
/* Check what next non-whitespace character is so we can tell if there
is the required parens if we have a BIND(C). */
@@ -7668,13 +7717,16 @@ gfc_match_subroutine (void)
if (sym->attr.is_bind_c == 1)
{
sym->attr.is_bind_c = 0;
- if (sym->old_symbol != NULL)
- gfc_error_now ("BIND(C) attribute at %L can only be used for "
- "variables or common blocks",
- &(sym->old_symbol->declared_at));
- else
- gfc_error_now ("BIND(C) attribute at %L can only be used for "
- "variables or common blocks", &gfc_current_locus);
+
+ if (gfc_state_stack->previous
+ && gfc_state_stack->previous->state != COMP_SUBMODULE)
+ {
+ locus loc;
+ loc = sym->old_symbol != NULL
+ ? sym->old_symbol->declared_at : gfc_current_locus;
+ gfc_error_now ("BIND(C) attribute at %L can only be used for "
+ "variables or common blocks", &loc);
+ }
}
/* C binding names are not allowed for internal procedures. */
@@ -7716,6 +7768,24 @@ gfc_match_subroutine (void)
return MATCH_ERROR;
}
+ /* F2018 C1550 (R1526) If MODULE appears in the prefix of a module
+ subprogram and a binding label is specified, it shall be the
+ same as the binding label specified in the corresponding module
+ procedure interface body. */
+ if (sym->attr.module_procedure && sym->old_symbol
+ && strcmp (sym->name, sym->old_symbol->name) == 0
+ && strcmp (sym->binding_label, sym->old_symbol->binding_label) != 0)
+ {
+ const char *null = "NULL", *s1, *s2;
+ s1 = sym->binding_label;
+ if (!s1) s1 = null;
+ s2 = sym->old_symbol->binding_label;
+ if (!s2) s2 = null;
+ gfc_error ("Mismatch in BIND(C) names (%qs/%qs) at %C", s1, s2);
+ sym->refs++; /* Needed to avoid an ICE in gfc_release_symbol */
+ return MATCH_ERROR;
+ }
+
/* Scan the dummy arguments for an alternate return. */
for (arg = sym->formal; arg; arg = arg->next)
if (!arg->sym)
@@ -10161,6 +10231,20 @@ gfc_match_derived_decl (void)
return MATCH_ERROR;
}
+ /* In free source form, need to check for TYPE XXX as oppose to TYPEXXX.
+ But, we need to simply return for TYPE(. */
+ if (m == MATCH_NO && gfc_current_form == FORM_FREE)
+ {
+ char c = gfc_peek_ascii_char ();
+ if (c == '(')
+ return m;
+ if (!gfc_is_whitespace (c))
+ {
+ gfc_error ("Mangled derived type definition at %C");
+ return MATCH_NO;
+ }
+ }
+
m = gfc_match (" %n ", name);
if (m != MATCH_YES)
return m;
@@ -10168,7 +10252,7 @@ gfc_match_derived_decl (void)
/* Make sure that we don't identify TYPE IS (...) as a parameterized
derived type named 'is'.
TODO Expand the check, when 'name' = "is" by matching " (tname) "
- and checking if this is a(n intrinsic) typename. his picks up
+ and checking if this is a(n intrinsic) typename. This picks up
misplaced TYPE IS statements such as in select_type_1.f03. */
if (gfc_peek_ascii_char () == '(')
{
@@ -11472,3 +11556,53 @@ gfc_match_gcc_builtin (void)
return MATCH_YES;
}
+
+/* Match an !GCC$ IVDEP statement.
+ When we come here, we have already matched the !GCC$ IVDEP string. */
+
+match
+gfc_match_gcc_ivdep (void)
+{
+ if (gfc_match_eos () == MATCH_YES)
+ {
+ directive_ivdep = true;
+ return MATCH_YES;
+ }
+
+ gfc_error ("Syntax error in !GCC$ IVDEP directive at %C");
+ return MATCH_ERROR;
+}
+
+/* Match an !GCC$ VECTOR statement.
+ When we come here, we have already matched the !GCC$ VECTOR string. */
+
+match
+gfc_match_gcc_vector (void)
+{
+ if (gfc_match_eos () == MATCH_YES)
+ {
+ directive_vector = true;
+ directive_novector = false;
+ return MATCH_YES;
+ }
+
+ gfc_error ("Syntax error in !GCC$ VECTOR directive at %C");
+ return MATCH_ERROR;
+}
+
+/* Match an !GCC$ NOVECTOR statement.
+ When we come here, we have already matched the !GCC$ NOVECTOR string. */
+
+match
+gfc_match_gcc_novector (void)
+{
+ if (gfc_match_eos () == MATCH_YES)
+ {
+ directive_novector = true;
+ directive_vector = false;
+ return MATCH_YES;
+ }
+
+ gfc_error ("Syntax error in !GCC$ NOVECTOR directive at %C");
+ return MATCH_ERROR;
+}