LCOV - code coverage report
Current view: top level - gcc/fortran - matchexp.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 85.8 % 472 405
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 20 20
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Expression parser.
       2              :    Copyright (C) 2000-2026 Free Software Foundation, Inc.
       3              :    Contributed by Andy Vaught
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify it under
       8              : the terms of the GNU General Public License as published by the Free
       9              : Software Foundation; either version 3, or (at your option) any later
      10              : version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15              : for more details.
      16              : 
      17              : You should have received a copy of the GNU General Public License
      18              : along with GCC; see the file COPYING3.  If not see
      19              : <http://www.gnu.org/licenses/>.  */
      20              : 
      21              : #include "config.h"
      22              : #include "system.h"
      23              : #include "coretypes.h"
      24              : #include "gfortran.h"
      25              : #include "arith.h"
      26              : #include "match.h"
      27              : 
      28              : static const char expression_syntax[] = N_("Syntax error in expression at %C");
      29              : 
      30              : 
      31              : /* Match a user-defined operator name.  This is a normal name with a
      32              :    few restrictions.  The error_flag controls whether an error is
      33              :    raised if 'true' or 'false' are used or not.  */
      34              : 
      35              : match
      36     11810668 : gfc_match_defined_op_name (char *result, int error_flag)
      37              : {
      38     11810668 :   static const char * const badops[] = {
      39              :     "and", "or", "not", "eqv", "neqv", "eq", "ne", "ge", "le", "lt", "gt",
      40              :       NULL
      41              :   };
      42              : 
      43     11810668 :   char name[GFC_MAX_SYMBOL_LEN + 1];
      44     11810668 :   locus old_loc;
      45     11810668 :   match m;
      46     11810668 :   int i;
      47              : 
      48     11810668 :   old_loc = gfc_current_locus;
      49              : 
      50     11810668 :   m = gfc_match (" . %n .", name);
      51     11810668 :   if (m != MATCH_YES)
      52              :     return m;
      53              : 
      54              :   /* .true. and .false. have interpretations as constants.  Trying to
      55              :      use these as operators will fail at a later time.  */
      56              : 
      57        57602 :   if (strcmp (name, "true") == 0 || strcmp (name, "false") == 0)
      58              :     {
      59        56549 :       if (error_flag)
      60            0 :         goto error;
      61        56549 :       gfc_current_locus = old_loc;
      62        56549 :       return MATCH_NO;
      63              :     }
      64              : 
      65        12635 :   for (i = 0; badops[i]; i++)
      66        11583 :     if (strcmp (badops[i], name) == 0)
      67            1 :       goto error;
      68              : 
      69         5713 :   for (i = 0; name[i]; i++)
      70         4697 :     if (!ISALPHA (name[i]))
      71              :       {
      72           36 :         gfc_error ("Bad character %qc in OPERATOR name at %C", name[i]);
      73           36 :         return MATCH_ERROR;
      74              :       }
      75              : 
      76         1016 :   strcpy (result, name);
      77         1016 :   return MATCH_YES;
      78              : 
      79            1 : error:
      80            1 :   gfc_error ("The name %qs cannot be used as a defined operator at %C",
      81              :              name);
      82              : 
      83            1 :   gfc_current_locus = old_loc;
      84            1 :   return MATCH_ERROR;
      85              : }
      86              : 
      87              : 
      88              : /* Match a user defined operator.  The symbol found must be an
      89              :    operator already.  */
      90              : 
      91              : static match
      92     11809173 : match_defined_operator (gfc_user_op **result)
      93              : {
      94     11809173 :   char name[GFC_MAX_SYMBOL_LEN + 1];
      95     11809173 :   match m;
      96              : 
      97     11809173 :   m = gfc_match_defined_op_name (name, 0);
      98     11809173 :   if (m != MATCH_YES)
      99              :     return m;
     100              : 
     101          591 :   *result = gfc_get_uop (name);
     102          591 :   return MATCH_YES;
     103              : }
     104              : 
     105              : 
     106              : /* Check to see if the given operator is next on the input.  If this
     107              :    is not the case, the parse pointer remains where it was.  */
     108              : 
     109              : static int
     110     76239293 : next_operator (gfc_intrinsic_op t)
     111              : {
     112     76239293 :   gfc_intrinsic_op u;
     113     76239293 :   locus old_loc;
     114              : 
     115     76239293 :   old_loc = gfc_current_locus;
     116     76239293 :   if (gfc_match_intrinsic_op (&u) == MATCH_YES && t == u)
     117              :     return 1;
     118              : 
     119     75428066 :   gfc_current_locus = old_loc;
     120     75428066 :   return 0;
     121              : }
     122              : 
     123              : 
     124              : /* Call the INTRINSIC_PARENTHESES function.  This is both
     125              :    used explicitly, as below, or by resolve.cc to generate
     126              :    temporaries.  */
     127              : 
     128              : gfc_expr *
     129        57889 : gfc_get_parentheses (gfc_expr *e)
     130              : {
     131        57889 :   gfc_expr *e2;
     132              : 
     133        57889 :   e2 = gfc_get_operator_expr (&e->where, INTRINSIC_PARENTHESES, e, NULL);
     134        57889 :   e2->ts = e->ts;
     135        57889 :   e2->rank = e->rank;
     136        57889 :   e2->corank = e->corank;
     137              : 
     138        57889 :   return e2;
     139              : }
     140              : 
     141              : /* Match a conditional expression.  */
     142              : 
     143              : static match
     144        58047 : match_conditional (gfc_expr **result)
     145              : {
     146        58047 :   gfc_expr *condition, *true_expr, *false_expr;
     147        58047 :   locus where;
     148        58047 :   match m;
     149              : 
     150        58047 :   where = gfc_current_locus;
     151              : 
     152        58047 :   m = gfc_match_expr (&condition);
     153        58047 :   if (m != MATCH_YES)
     154              :     {
     155           70 :       gfc_error (expression_syntax);
     156           70 :       return MATCH_ERROR;
     157              :     }
     158              : 
     159        57977 :   m = gfc_match_char ('?');
     160        57977 :   if (m != MATCH_YES)
     161              :     {
     162        57753 :       *result = condition;
     163        57753 :       return MATCH_YES;
     164              :     }
     165          224 :   else if (!gfc_notify_std (GFC_STD_F2023, "Conditional expression at %L",
     166              :                             &where))
     167              :     {
     168            1 :       gfc_free_expr (condition);
     169            1 :       return MATCH_ERROR;
     170              :     }
     171              : 
     172          223 :   gfc_gobble_whitespace ();
     173          223 :   m = gfc_match_expr (&true_expr);
     174          223 :   if (m != MATCH_YES)
     175              :     {
     176            0 :       gfc_free_expr (condition);
     177            0 :       return m;
     178              :     }
     179              : 
     180          223 :   m = gfc_match_char (':');
     181          223 :   if (m != MATCH_YES)
     182              :     {
     183            1 :       gfc_error ("Expected ':' in conditional expression at %C");
     184            1 :       gfc_free_expr (condition);
     185            1 :       gfc_free_expr (true_expr);
     186            1 :       return MATCH_ERROR;
     187              :     }
     188              : 
     189          222 :   m = match_conditional (&false_expr);
     190          222 :   if (m != MATCH_YES)
     191              :     {
     192            0 :       gfc_free_expr (condition);
     193            0 :       gfc_free_expr (true_expr);
     194            0 :       return m;
     195              :     }
     196              : 
     197          222 :   *result = gfc_get_conditional_expr (&where, condition, true_expr, false_expr);
     198          222 :   return MATCH_YES;
     199              : }
     200              : 
     201              : /* Match a primary expression.  */
     202              : 
     203              : static match
     204      7033273 : match_primary (gfc_expr **result)
     205              : {
     206      7033273 :   match m;
     207      7033273 :   gfc_expr *e;
     208              : 
     209      7033273 :   m = gfc_match_literal_constant (result, 0);
     210      7033273 :   if (m != MATCH_NO)
     211              :     return m;
     212              : 
     213      4334352 :   m = gfc_match_array_constructor (result);
     214      4334352 :   if (m != MATCH_NO)
     215              :     return m;
     216              : 
     217      4202811 :   m = gfc_match_rvalue (result);
     218      4202811 :   if (m != MATCH_NO)
     219              :     return m;
     220              : 
     221              :   /* Match an expression in parentheses.  */
     222       202837 :   if (gfc_match_char ('(') != MATCH_YES)
     223              :     return MATCH_NO;
     224              : 
     225        57825 :   m = match_conditional (&e);
     226        57825 :   if (m != MATCH_YES)
     227              :     return m;
     228              : 
     229        57753 :   m = gfc_match_char (')');
     230        57753 :   if (m == MATCH_NO)
     231         2438 :     gfc_error ("Expected a right parenthesis in expression at %C");
     232              : 
     233              :   /* Now we have the expression inside the parentheses, build the expression
     234              :      pointing to it. By 7.1.7.2, any expression in parentheses shall be treated
     235              :      as a data entity.
     236              :      Note that if the expression is a conditional expression, we will omit the
     237              :      extra parentheses.  */
     238        57753 :   *result = e->expr_type == EXPR_CONDITIONAL ? e : gfc_get_parentheses (e);
     239              : 
     240        57753 :   if (m != MATCH_YES)
     241              :     {
     242         2438 :       gfc_free_expr (*result);
     243         2438 :       return MATCH_ERROR;
     244              :     }
     245              : 
     246              :   return MATCH_YES;
     247              : }
     248              : 
     249              : 
     250              : /* Match a level 1 expression.  */
     251              : 
     252              : static match
     253      7033273 : match_level_1 (gfc_expr **result)
     254              : {
     255      7033273 :   gfc_user_op *uop;
     256      7033273 :   gfc_expr *e, *f;
     257      7033273 :   locus where;
     258      7033273 :   match m;
     259              : 
     260      7033273 :   gfc_gobble_whitespace ();
     261      7033273 :   where = gfc_current_locus;
     262      7033273 :   uop = NULL;
     263      7033273 :   m = match_defined_operator (&uop);
     264      7033273 :   if (m == MATCH_ERROR)
     265              :     return m;
     266              : 
     267      7033273 :   m = match_primary (&e);
     268      7033273 :   if (m != MATCH_YES)
     269              :     return m;
     270              : 
     271      6257696 :   if (uop == NULL)
     272      6257464 :     *result = e;
     273              :   else
     274              :     {
     275          232 :       f = gfc_get_operator_expr (&where, INTRINSIC_USER, e, NULL);
     276          232 :       f->value.op.uop = uop;
     277          232 :       *result = f;
     278              :     }
     279              : 
     280              :   return MATCH_YES;
     281              : }
     282              : 
     283              : 
     284              : /* As a GNU extension we support an expanded level-2 expression syntax.
     285              :    Via this extension we support (arbitrary) nesting of unary plus and
     286              :    minus operations following unary and binary operators, such as **.
     287              :    The grammar of section 7.1.1.3 is effectively rewritten as:
     288              : 
     289              :         R704  mult-operand     is level-1-expr [ power-op ext-mult-operand ]
     290              :         R704' ext-mult-operand is add-op ext-mult-operand
     291              :                                or mult-operand
     292              :         R705  add-operand      is add-operand mult-op ext-mult-operand
     293              :                                or mult-operand
     294              :         R705' ext-add-operand  is add-op ext-add-operand
     295              :                                or add-operand
     296              :         R706  level-2-expr     is [ level-2-expr ] add-op ext-add-operand
     297              :                                or add-operand
     298              :  */
     299              : 
     300              : static match match_ext_mult_operand (gfc_expr **result);
     301              : static match match_ext_add_operand (gfc_expr **result);
     302              : 
     303              : static int
     304     13279833 : match_add_op (void)
     305              : {
     306     13279833 :   if (next_operator (INTRINSIC_MINUS))
     307              :     return -1;
     308     13071948 :   if (next_operator (INTRINSIC_PLUS))
     309        69427 :     return 1;
     310              :   return 0;
     311              : }
     312              : 
     313              : 
     314              : static match
     315      7033273 : match_mult_operand (gfc_expr **result)
     316              : {
     317              :   /* Workaround -Wmaybe-uninitialized false positive during
     318              :      profiledbootstrap by initializing them.  */
     319      7033273 :   gfc_expr *e = NULL, *exp, *r;
     320      7033273 :   locus where;
     321      7033273 :   match m;
     322              : 
     323      7033273 :   m = match_level_1 (&e);
     324      7033273 :   if (m != MATCH_YES)
     325              :     return m;
     326              : 
     327      6257696 :   if (!next_operator (INTRINSIC_POWER))
     328              :     {
     329      6189037 :       *result = e;
     330      6189037 :       return MATCH_YES;
     331              :     }
     332              : 
     333        68659 :   where = gfc_current_locus;
     334              : 
     335        68659 :   m = match_ext_mult_operand (&exp);
     336        68659 :   if (m == MATCH_NO)
     337            0 :     gfc_error ("Expected exponent in expression at %C");
     338        68659 :   if (m != MATCH_YES)
     339              :     {
     340            1 :       gfc_free_expr (e);
     341            1 :       return MATCH_ERROR;
     342              :     }
     343              : 
     344        68658 :   r = gfc_power (e, exp);
     345        68658 :   if (r == NULL)
     346              :     {
     347            0 :       gfc_free_expr (e);
     348            0 :       gfc_free_expr (exp);
     349            0 :       return MATCH_ERROR;
     350              :     }
     351              : 
     352        68658 :   r->where = where;
     353        68658 :   *result = r;
     354              : 
     355        68658 :   return MATCH_YES;
     356              : }
     357              : 
     358              : 
     359              : static match
     360       209128 : match_ext_mult_operand (gfc_expr **result)
     361              : {
     362       209128 :   gfc_expr *all, *e;
     363       209128 :   locus where;
     364       209128 :   match m;
     365       209128 :   int i;
     366              : 
     367       209128 :   where = gfc_current_locus;
     368       209128 :   i = match_add_op ();
     369              : 
     370       209128 :   if (i == 0)
     371       209115 :     return match_mult_operand (result);
     372              : 
     373           13 :   if (gfc_notification_std (GFC_STD_GNU) == ERROR)
     374              :     {
     375            0 :       gfc_error ("Extension: Unary operator following "
     376              :                  "arithmetic operator (use parentheses) at %C");
     377            0 :       return MATCH_ERROR;
     378              :     }
     379              :   else
     380           13 :     gfc_warning (0, "Extension: Unary operator following "
     381              :                  "arithmetic operator (use parentheses) at %C");
     382              : 
     383           13 :   m = match_ext_mult_operand (&e);
     384           13 :   if (m != MATCH_YES)
     385              :     return m;
     386              : 
     387           13 :   if (i == -1)
     388            7 :     all = gfc_uminus (e);
     389              :   else
     390            6 :     all = gfc_uplus (e);
     391              : 
     392           13 :   if (all == NULL)
     393              :     {
     394            0 :       gfc_free_expr (e);
     395            0 :       return MATCH_ERROR;
     396              :     }
     397              : 
     398           13 :   all->where = where;
     399           13 :   *result = all;
     400           13 :   return MATCH_YES;
     401              : }
     402              : 
     403              : 
     404              : static match
     405      6824158 : match_add_operand (gfc_expr **result)
     406              : {
     407      6824158 :   gfc_expr *all, *e, *total;
     408      6824158 :   locus where, old_loc;
     409      6824158 :   match m;
     410      6824158 :   gfc_intrinsic_op i;
     411              : 
     412      6824158 :   m = match_mult_operand (&all);
     413      6824158 :   if (m != MATCH_YES)
     414              :     return m;
     415              : 
     416      6270856 :   for (;;)
     417              :     {
     418              :       /* Build up a string of products or quotients.  */
     419              : 
     420      6189029 :       old_loc = gfc_current_locus;
     421              : 
     422      6189029 :       if (next_operator (INTRINSIC_TIMES))
     423              :         i = INTRINSIC_TIMES;
     424              :       else
     425              :         {
     426      6120425 :           if (next_operator (INTRINSIC_DIVIDE))
     427              :             i = INTRINSIC_DIVIDE;
     428              :           else
     429              :             break;
     430              :         }
     431              : 
     432       140456 :       where = gfc_current_locus;
     433              : 
     434       140456 :       m = match_ext_mult_operand (&e);
     435       140456 :       if (m == MATCH_NO)
     436              :         {
     437        58621 :           gfc_current_locus = old_loc;
     438        58621 :           break;
     439              :         }
     440              : 
     441        81835 :       if (m == MATCH_ERROR)
     442              :         {
     443            0 :           gfc_free_expr (all);
     444            0 :           return MATCH_ERROR;
     445              :         }
     446              : 
     447        81835 :       if (i == INTRINSIC_TIMES)
     448        68604 :         total = gfc_multiply (all, e);
     449              :       else
     450        13231 :         total = gfc_divide (all, e);
     451              : 
     452        81835 :       if (total == NULL)
     453              :         {
     454            8 :           gfc_free_expr (all);
     455            8 :           gfc_free_expr (e);
     456            8 :           return MATCH_ERROR;
     457              :         }
     458              : 
     459        81827 :       all = total;
     460        81827 :       all->where = where;
     461              :     }
     462              : 
     463      6107194 :   *result = all;
     464      6107194 :   return MATCH_YES;
     465              : }
     466              : 
     467              : 
     468              : static match
     469       277299 : match_ext_add_operand (gfc_expr **result)
     470              : {
     471       277299 :   gfc_expr *all, *e;
     472       277299 :   locus where;
     473       277299 :   match m;
     474       277299 :   int i;
     475              : 
     476       277299 :   where = gfc_current_locus;
     477       277299 :   i = match_add_op ();
     478              : 
     479       277299 :   if (i == 0)
     480       277299 :     return match_add_operand (result);
     481              : 
     482            0 :   if (gfc_notification_std (GFC_STD_GNU) == ERROR)
     483              :     {
     484            0 :       gfc_error ("Extension: Unary operator following "
     485              :                  "arithmetic operator (use parentheses) at %C");
     486            0 :       return MATCH_ERROR;
     487              :     }
     488              :   else
     489            0 :     gfc_warning (0, "Extension: Unary operator following "
     490              :                 "arithmetic operator (use parentheses) at %C");
     491              : 
     492            0 :   m = match_ext_add_operand (&e);
     493            0 :   if (m != MATCH_YES)
     494              :     return m;
     495              : 
     496            0 :   if (i == -1)
     497            0 :     all = gfc_uminus (e);
     498              :   else
     499            0 :     all = gfc_uplus (e);
     500              : 
     501            0 :   if (all == NULL)
     502              :     {
     503            0 :       gfc_free_expr (e);
     504            0 :       return MATCH_ERROR;
     505              :     }
     506              : 
     507            0 :   all->where = where;
     508            0 :   *result = all;
     509            0 :   return MATCH_YES;
     510              : }
     511              : 
     512              : 
     513              : /* Match a level 2 expression.  */
     514              : 
     515              : static match
     516      6686213 : match_level_2 (gfc_expr **result)
     517              : {
     518      6686213 :   gfc_expr *all, *e, *total;
     519      6686213 :   locus where;
     520      6686213 :   match m;
     521      6686213 :   int i;
     522              : 
     523      6686213 :   where = gfc_current_locus;
     524      6686213 :   i = match_add_op ();
     525              : 
     526      6686213 :   if (i != 0)
     527              :     {
     528       139354 :       m = match_ext_add_operand (&e);
     529       139354 :       if (m == MATCH_NO)
     530              :         {
     531            8 :           gfc_error (expression_syntax);
     532            8 :           m = MATCH_ERROR;
     533              :         }
     534              :     }
     535              :   else
     536      6546859 :     m = match_add_operand (&e);
     537              : 
     538      6686213 :   if (m != MATCH_YES)
     539       716961 :     return m;
     540              : 
     541      5969252 :   if (i == 0)
     542      5829912 :     all = e;
     543              :   else
     544              :     {
     545       139340 :       if (i == -1)
     546       138970 :         all = gfc_uminus (e);
     547              :       else
     548          370 :         all = gfc_uplus (e);
     549              : 
     550       139340 :       if (all == NULL)
     551              :         {
     552            1 :           gfc_free_expr (e);
     553            1 :           return MATCH_ERROR;
     554              :         }
     555              :     }
     556              : 
     557      5969251 :   all->where = where;
     558              : 
     559              :   /* Append add-operands to the sum.  */
     560              : 
     561      6245135 :   for (;;)
     562              :     {
     563      6107193 :       where = gfc_current_locus;
     564      6107193 :       i = match_add_op ();
     565      6107193 :       if (i == 0)
     566              :         break;
     567              : 
     568       137945 :       m = match_ext_add_operand (&e);
     569       137945 :       if (m == MATCH_NO)
     570            0 :         gfc_error (expression_syntax);
     571       137945 :       if (m != MATCH_YES)
     572              :         {
     573            3 :           gfc_free_expr (all);
     574            3 :           return MATCH_ERROR;
     575              :         }
     576              : 
     577       137942 :       if (i == -1)
     578        68894 :         total = gfc_subtract (all, e);
     579              :       else
     580        69048 :         total = gfc_add (all, e);
     581              : 
     582       137942 :       if (total == NULL)
     583              :         {
     584            0 :           gfc_free_expr (all);
     585            0 :           gfc_free_expr (e);
     586            0 :           return MATCH_ERROR;
     587              :         }
     588              : 
     589       137942 :       all = total;
     590       137942 :       all->where = where;
     591              :     }
     592              : 
     593      5969248 :   *result = all;
     594      5969248 :   return MATCH_YES;
     595              : }
     596              : 
     597              : 
     598              : /* Match a level three expression.  */
     599              : 
     600              : static match
     601      6680688 : match_level_3 (gfc_expr **result)
     602              : {
     603      6680688 :   gfc_expr *all, *e, *total = NULL;
     604      6680688 :   locus where;
     605      6680688 :   match m;
     606              : 
     607      6680688 :   m = match_level_2 (&all);
     608      6680688 :   if (m != MATCH_YES)
     609              :     return m;
     610              : 
     611      5974765 :   for (;;)
     612              :     {
     613      5969247 :       if (!next_operator (INTRINSIC_CONCAT))
     614              :         break;
     615              : 
     616         5525 :       where = gfc_current_locus;
     617              : 
     618         5525 :       m = match_level_2 (&e);
     619         5525 :       if (m == MATCH_NO)
     620            0 :         gfc_error (expression_syntax);
     621         5525 :       if (m != MATCH_YES)
     622              :         {
     623            6 :           gfc_free_expr (all);
     624            6 :           return MATCH_ERROR;
     625              :         }
     626              : 
     627         5519 :       total = gfc_concat (all, e);
     628         5519 :       if (total == NULL)
     629              :         {
     630            1 :           gfc_free_expr (all);
     631            1 :           gfc_free_expr (e);
     632            1 :           return MATCH_ERROR;
     633              :         }
     634              : 
     635         5518 :       all = total;
     636         5518 :       all->where = where;
     637              :     }
     638              : 
     639      5963722 :   *result = all;
     640      5963722 :   return MATCH_YES;
     641              : }
     642              : 
     643              : 
     644              : /* Match a level 4 expression.  */
     645              : 
     646              : static match
     647      5734594 : match_level_4 (gfc_expr **result)
     648              : {
     649      5734594 :   gfc_expr *left, *right, *r;
     650      5734594 :   gfc_intrinsic_op i;
     651      5734594 :   locus old_loc;
     652      5734594 :   locus where;
     653      5734594 :   match m;
     654              : 
     655      5734594 :   m = match_level_3 (&left);
     656      5734594 :   if (m != MATCH_YES)
     657              :     return m;
     658              : 
     659      5017628 :   old_loc = gfc_current_locus;
     660              : 
     661      5017628 :   if (gfc_match_intrinsic_op (&i) != MATCH_YES)
     662              :     {
     663      3949683 :       *result = left;
     664      3949683 :       return MATCH_YES;
     665              :     }
     666              : 
     667      1067945 :   if (i != INTRINSIC_EQ && i != INTRINSIC_NE && i != INTRINSIC_GE
     668       409132 :       && i != INTRINSIC_LE && i != INTRINSIC_LT && i != INTRINSIC_GT
     669       364802 :       && i != INTRINSIC_EQ_OS && i != INTRINSIC_NE_OS && i != INTRINSIC_GE_OS
     670       137545 :       && i != INTRINSIC_LE_OS && i != INTRINSIC_LT_OS && i != INTRINSIC_GT_OS)
     671              :     {
     672       121851 :       gfc_current_locus = old_loc;
     673       121851 :       *result = left;
     674       121851 :       return MATCH_YES;
     675              :     }
     676              : 
     677       946094 :   where = gfc_current_locus;
     678              : 
     679       946094 :   m = match_level_3 (&right);
     680       946094 :   if (m == MATCH_NO)
     681            0 :     gfc_error (expression_syntax);
     682       946094 :   if (m != MATCH_YES)
     683              :     {
     684            0 :       gfc_free_expr (left);
     685            0 :       return MATCH_ERROR;
     686              :     }
     687              : 
     688       946094 :   switch (i)
     689              :     {
     690        33565 :     case INTRINSIC_EQ:
     691        33565 :     case INTRINSIC_EQ_OS:
     692        33565 :       r = gfc_eq (left, right, i);
     693        33565 :       break;
     694              : 
     695       847811 :     case INTRINSIC_NE:
     696       847811 :     case INTRINSIC_NE_OS:
     697       847811 :       r = gfc_ne (left, right, i);
     698       847811 :       break;
     699              : 
     700        11189 :     case INTRINSIC_LT:
     701        11189 :     case INTRINSIC_LT_OS:
     702        11189 :       r = gfc_lt (left, right, i);
     703        11189 :       break;
     704              : 
     705         7395 :     case INTRINSIC_LE:
     706         7395 :     case INTRINSIC_LE_OS:
     707         7395 :       r = gfc_le (left, right, i);
     708         7395 :       break;
     709              : 
     710        41440 :     case INTRINSIC_GT:
     711        41440 :     case INTRINSIC_GT_OS:
     712        41440 :       r = gfc_gt (left, right, i);
     713        41440 :       break;
     714              : 
     715         4694 :     case INTRINSIC_GE:
     716         4694 :     case INTRINSIC_GE_OS:
     717         4694 :       r = gfc_ge (left, right, i);
     718         4694 :       break;
     719              : 
     720            0 :     default:
     721            0 :       gfc_internal_error ("match_level_4(): Bad operator");
     722              :     }
     723              : 
     724       946094 :   if (r == NULL)
     725              :     {
     726            0 :       gfc_free_expr (left);
     727            0 :       gfc_free_expr (right);
     728            0 :       return MATCH_ERROR;
     729              :     }
     730              : 
     731       946094 :   r->where = where;
     732       946094 :   *result = r;
     733              : 
     734       946094 :   return MATCH_YES;
     735              : }
     736              : 
     737              : 
     738              : static match
     739      5734594 : match_and_operand (gfc_expr **result)
     740              : {
     741      5734594 :   gfc_expr *e, *r;
     742      5734594 :   locus where;
     743      5734594 :   match m;
     744      5734594 :   int i;
     745              : 
     746      5734594 :   i = next_operator (INTRINSIC_NOT);
     747      5734594 :   where = gfc_current_locus;
     748              : 
     749      5734594 :   m = match_level_4 (&e);
     750      5734594 :   if (m != MATCH_YES)
     751              :     return m;
     752              : 
     753      5017628 :   r = e;
     754      5017628 :   if (i)
     755              :     {
     756        77547 :       r = gfc_not (e);
     757        77547 :       if (r == NULL)
     758              :         {
     759            0 :           gfc_free_expr (e);
     760            0 :           return MATCH_ERROR;
     761              :         }
     762              :     }
     763              : 
     764      5017628 :   r->where = where;
     765      5017628 :   *result = r;
     766              : 
     767      5017628 :   return MATCH_YES;
     768              : }
     769              : 
     770              : 
     771              : static match
     772      5717537 : match_or_operand (gfc_expr **result)
     773              : {
     774      5717537 :   gfc_expr *all, *e, *total;
     775      5717537 :   locus where;
     776      5717537 :   match m;
     777              : 
     778      5717537 :   m = match_and_operand (&all);
     779      5717537 :   if (m != MATCH_YES)
     780              :     return m;
     781              : 
     782      5034685 :   for (;;)
     783              :     {
     784      5017628 :       if (!next_operator (INTRINSIC_AND))
     785              :         break;
     786        17057 :       where = gfc_current_locus;
     787              : 
     788        17057 :       m = match_and_operand (&e);
     789        17057 :       if (m == MATCH_NO)
     790            0 :         gfc_error (expression_syntax);
     791        17057 :       if (m != MATCH_YES)
     792              :         {
     793            0 :           gfc_free_expr (all);
     794            0 :           return MATCH_ERROR;
     795              :         }
     796              : 
     797        17057 :       total = gfc_and (all, e);
     798        17057 :       if (total == NULL)
     799              :         {
     800            0 :           gfc_free_expr (all);
     801            0 :           gfc_free_expr (e);
     802            0 :           return MATCH_ERROR;
     803              :         }
     804              : 
     805        17057 :       all = total;
     806        17057 :       all->where = where;
     807              :     }
     808              : 
     809      5000571 :   *result = all;
     810      5000571 :   return MATCH_YES;
     811              : }
     812              : 
     813              : 
     814              : static match
     815      5517117 : match_equiv_operand (gfc_expr **result)
     816              : {
     817      5517117 :   gfc_expr *all, *e, *total;
     818      5517117 :   locus where;
     819      5517117 :   match m;
     820              : 
     821      5517117 :   m = match_or_operand (&all);
     822      5517117 :   if (m != MATCH_YES)
     823              :     return m;
     824              : 
     825      5200991 :   for (;;)
     826              :     {
     827      5000571 :       if (!next_operator (INTRINSIC_OR))
     828              :         break;
     829       200420 :       where = gfc_current_locus;
     830              : 
     831       200420 :       m = match_or_operand (&e);
     832       200420 :       if (m == MATCH_NO)
     833            0 :         gfc_error (expression_syntax);
     834       200420 :       if (m != MATCH_YES)
     835              :         {
     836            0 :           gfc_free_expr (all);
     837            0 :           return MATCH_ERROR;
     838              :         }
     839              : 
     840       200420 :       total = gfc_or (all, e);
     841       200420 :       if (total == NULL)
     842              :         {
     843            0 :           gfc_free_expr (all);
     844            0 :           gfc_free_expr (e);
     845            0 :           return MATCH_ERROR;
     846              :         }
     847              : 
     848       200420 :       all = total;
     849       200420 :       all->where = where;
     850              :     }
     851              : 
     852      4800151 :   *result = all;
     853      4800151 :   return MATCH_YES;
     854              : }
     855              : 
     856              : 
     857              : /* Match a level 5 expression.  */
     858              : 
     859              : static match
     860      5492866 : match_level_5 (gfc_expr **result)
     861              : {
     862      5492866 :   gfc_expr *all, *e, *total;
     863      5492866 :   locus where;
     864      5492866 :   match m;
     865      5492866 :   gfc_intrinsic_op i;
     866              : 
     867      5492866 :   m = match_equiv_operand (&all);
     868      5492866 :   if (m != MATCH_YES)
     869              :     return m;
     870              : 
     871      4824402 :   for (;;)
     872              :     {
     873      4800151 :       if (next_operator (INTRINSIC_EQV))
     874              :         i = INTRINSIC_EQV;
     875              :       else
     876              :         {
     877      4798171 :           if (next_operator (INTRINSIC_NEQV))
     878              :             i = INTRINSIC_NEQV;
     879              :           else
     880              :             break;
     881              :         }
     882              : 
     883        24251 :       where = gfc_current_locus;
     884              : 
     885        24251 :       m = match_equiv_operand (&e);
     886        24251 :       if (m == MATCH_NO)
     887            0 :         gfc_error (expression_syntax);
     888        24251 :       if (m != MATCH_YES)
     889              :         {
     890            0 :           gfc_free_expr (all);
     891            0 :           return MATCH_ERROR;
     892              :         }
     893              : 
     894        24251 :       if (i == INTRINSIC_EQV)
     895         1980 :         total = gfc_eqv (all, e);
     896              :       else
     897        22271 :         total = gfc_neqv (all, e);
     898              : 
     899        24251 :       if (total == NULL)
     900              :         {
     901            0 :           gfc_free_expr (all);
     902            0 :           gfc_free_expr (e);
     903            0 :           return MATCH_ERROR;
     904              :         }
     905              : 
     906        24251 :       all = total;
     907        24251 :       all->where = where;
     908              :     }
     909              : 
     910      4775900 :   *result = all;
     911      4775900 :   return MATCH_YES;
     912              : }
     913              : 
     914              : 
     915              : /* Match an expression.  At this level, we are stringing together
     916              :    level 5 expressions separated by binary operators.  */
     917              : 
     918              : match
     919      5492508 : gfc_match_expr (gfc_expr **result)
     920              : {
     921      5492508 :   gfc_expr *all, *e;
     922      5492508 :   gfc_user_op *uop;
     923      5492508 :   locus where;
     924      5492508 :   match m;
     925              : 
     926      5492508 :   m = match_level_5 (&all);
     927      5492508 :   if (m != MATCH_YES)
     928              :     return m;
     929              : 
     930      4776258 :   for (;;)
     931              :     {
     932      4775900 :       uop = NULL;
     933      4775900 :       m = match_defined_operator (&uop);
     934      4775900 :       if (m == MATCH_NO)
     935              :         break;
     936          394 :       if (m == MATCH_ERROR)
     937              :         {
     938           36 :           gfc_free_expr (all);
     939           36 :           return MATCH_ERROR;
     940              :         }
     941              : 
     942          358 :       where = gfc_current_locus;
     943              : 
     944          358 :       m = match_level_5 (&e);
     945          358 :       if (m == MATCH_NO)
     946            0 :         gfc_error (expression_syntax);
     947          358 :       if (m != MATCH_YES)
     948              :         {
     949            0 :           gfc_free_expr (all);
     950            0 :           return MATCH_ERROR;
     951              :         }
     952              : 
     953          358 :       all = gfc_get_operator_expr (&where, INTRINSIC_USER, all, e);
     954          358 :       all->value.op.uop = uop;
     955              :     }
     956              : 
     957      4775506 :   *result = all;
     958      4775506 :   return MATCH_YES;
     959              : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.