LCOV - code coverage report
Current view: top level - Python - ast.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit acb105a7c1f] Lines: 585 676 86.5 %
Date: 2022-07-20 13:12:14 Functions: 20 23 87.0 %
Branches: 574 766 74.9 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * This file exposes PyAST_Validate interface to check the integrity
       3                 :            :  * of the given abstract syntax tree (potentially constructed manually).
       4                 :            :  */
       5                 :            : #include "Python.h"
       6                 :            : #include "pycore_ast.h"           // asdl_stmt_seq
       7                 :            : #include "pycore_pystate.h"       // _PyThreadState_GET()
       8                 :            : 
       9                 :            : #include <assert.h>
      10                 :            : #include <stdbool.h>
      11                 :            : 
      12                 :            : struct validator {
      13                 :            :     int recursion_depth;            /* current recursion depth */
      14                 :            :     int recursion_limit;            /* recursion limit */
      15                 :            : };
      16                 :            : 
      17                 :            : static int validate_stmts(struct validator *, asdl_stmt_seq *);
      18                 :            : static int validate_exprs(struct validator *, asdl_expr_seq *, expr_context_ty, int);
      19                 :            : static int validate_patterns(struct validator *, asdl_pattern_seq *, int);
      20                 :            : static int _validate_nonempty_seq(asdl_seq *, const char *, const char *);
      21                 :            : static int validate_stmt(struct validator *, stmt_ty);
      22                 :            : static int validate_expr(struct validator *, expr_ty, expr_context_ty);
      23                 :            : static int validate_pattern(struct validator *, pattern_ty, int);
      24                 :            : 
      25                 :            : #define VALIDATE_POSITIONS(node) \
      26                 :            :     if (node->lineno > node->end_lineno) { \
      27                 :            :         PyErr_Format(PyExc_ValueError, \
      28                 :            :                      "AST node line range (%d, %d) is not valid", \
      29                 :            :                      node->lineno, node->end_lineno); \
      30                 :            :         return 0; \
      31                 :            :     } \
      32                 :            :     if ((node->lineno < 0 && node->end_lineno != node->lineno) || \
      33                 :            :         (node->col_offset < 0 && node->col_offset != node->end_col_offset)) { \
      34                 :            :         PyErr_Format(PyExc_ValueError, \
      35                 :            :                      "AST node column range (%d, %d) for line range (%d, %d) is not valid", \
      36                 :            :                      node->col_offset, node->end_col_offset, node->lineno, node->end_lineno); \
      37                 :            :         return 0; \
      38                 :            :     } \
      39                 :            :     if (node->lineno == node->end_lineno && node->col_offset > node->end_col_offset) { \
      40                 :            :         PyErr_Format(PyExc_ValueError, \
      41                 :            :                      "line %d, column %d-%d is not a valid range", \
      42                 :            :                      node->lineno, node->col_offset, node->end_col_offset); \
      43                 :            :         return 0; \
      44                 :            :     }
      45                 :            : 
      46                 :            : static int
      47                 :     119382 : validate_name(PyObject *name)
      48                 :            : {
      49                 :            :     assert(PyUnicode_Check(name));
      50                 :            :     static const char * const forbidden[] = {
      51                 :            :         "None",
      52                 :            :         "True",
      53                 :            :         "False",
      54                 :            :         NULL
      55                 :            :     };
      56         [ +  + ]:     477515 :     for (int i = 0; forbidden[i] != NULL; i++) {
      57         [ +  + ]:     358140 :         if (_PyUnicode_EqualToASCIIString(name, forbidden[i])) {
      58                 :          7 :             PyErr_Format(PyExc_ValueError, "identifier field can't represent '%s' constant", forbidden[i]);
      59                 :          7 :             return 0;
      60                 :            :         }
      61                 :            :     }
      62                 :     119375 :     return 1;
      63                 :            : }
      64                 :            : 
      65                 :            : static int
      66                 :        612 : validate_comprehension(struct validator *state, asdl_comprehension_seq *gens)
      67                 :            : {
      68                 :            :     Py_ssize_t i;
      69   [ +  -  +  + ]:        612 :     if (!asdl_seq_LEN(gens)) {
      70                 :          4 :         PyErr_SetString(PyExc_ValueError, "comprehension with no generators");
      71                 :          4 :         return 0;
      72                 :            :     }
      73   [ +  -  +  + ]:       1227 :     for (i = 0; i < asdl_seq_LEN(gens); i++) {
      74                 :        635 :         comprehension_ty comp = asdl_seq_GET(gens, i);
      75   [ +  +  +  + ]:       1266 :         if (!validate_expr(state, comp->target, Store) ||
      76         [ +  + ]:       1258 :             !validate_expr(state, comp->iter, Load) ||
      77                 :        627 :             !validate_exprs(state, comp->ifs, Load, 0))
      78                 :         16 :             return 0;
      79                 :            :     }
      80                 :        592 :     return 1;
      81                 :            : }
      82                 :            : 
      83                 :            : static int
      84                 :      30949 : validate_keywords(struct validator *state, asdl_keyword_seq *keywords)
      85                 :            : {
      86                 :            :     Py_ssize_t i;
      87   [ +  -  +  + ]:      34250 :     for (i = 0; i < asdl_seq_LEN(keywords); i++)
      88         [ +  + ]:       3303 :         if (!validate_expr(state, (asdl_seq_GET(keywords, i))->value, Load))
      89                 :          2 :             return 0;
      90                 :      30947 :     return 1;
      91                 :            : }
      92                 :            : 
      93                 :            : static int
      94                 :      22794 : validate_args(struct validator *state, asdl_arg_seq *args)
      95                 :            : {
      96                 :            :     Py_ssize_t i;
      97   [ +  -  +  + ]:      37517 :     for (i = 0; i < asdl_seq_LEN(args); i++) {
      98                 :      14729 :         arg_ty arg = asdl_seq_GET(args, i);
      99   [ -  +  -  +  :      14729 :         VALIDATE_POSITIONS(arg);
          -  -  -  +  -  
             -  +  -  -  
                      + ]
     100   [ +  +  +  + ]:      14729 :         if (arg->annotation && !validate_expr(state, arg->annotation, Load))
     101                 :          6 :             return 0;
     102                 :            :     }
     103                 :      22788 :     return 1;
     104                 :            : }
     105                 :            : 
     106                 :            : static const char *
     107                 :        173 : expr_context_name(expr_context_ty ctx)
     108                 :            : {
     109   [ +  +  +  - ]:        173 :     switch (ctx) {
     110                 :         86 :     case Load:
     111                 :         86 :         return "Load";
     112                 :         86 :     case Store:
     113                 :         86 :         return "Store";
     114                 :          1 :     case Del:
     115                 :          1 :         return "Del";
     116                 :            :     // No default case so compiler emits warning for unhandled cases
     117                 :            :     }
     118                 :          0 :     Py_UNREACHABLE();
     119                 :            : }
     120                 :            : 
     121                 :            : static int
     122                 :       7600 : validate_arguments(struct validator *state, arguments_ty args)
     123                 :            : {
     124   [ +  +  +  + ]:       7600 :     if (!validate_args(state, args->posonlyargs) || !validate_args(state, args->args)) {
     125                 :          4 :         return 0;
     126                 :            :     }
     127   [ +  +  +  + ]:       7596 :     if (args->vararg && args->vararg->annotation
     128         [ -  + ]:         10 :         && !validate_expr(state, args->vararg->annotation, Load)) {
     129                 :          0 :             return 0;
     130                 :            :     }
     131         [ +  + ]:       7596 :     if (!validate_args(state, args->kwonlyargs))
     132                 :          2 :         return 0;
     133   [ +  +  +  + ]:       7594 :     if (args->kwarg && args->kwarg->annotation
     134         [ -  + ]:          4 :         && !validate_expr(state, args->kwarg->annotation, Load)) {
     135                 :          0 :             return 0;
     136                 :            :     }
     137   [ +  -  +  -  :       7594 :     if (asdl_seq_LEN(args->defaults) > asdl_seq_LEN(args->posonlyargs) + asdl_seq_LEN(args->args)) {
             +  -  +  + ]
     138                 :          2 :         PyErr_SetString(PyExc_ValueError, "more positional defaults than args on arguments");
     139                 :          2 :         return 0;
     140                 :            :     }
     141   [ +  -  +  -  :       7592 :     if (asdl_seq_LEN(args->kw_defaults) != asdl_seq_LEN(args->kwonlyargs)) {
                   +  + ]
     142                 :          2 :         PyErr_SetString(PyExc_ValueError, "length of kwonlyargs is not the same as "
     143                 :            :                         "kw_defaults on arguments");
     144                 :          2 :         return 0;
     145                 :            :     }
     146   [ +  +  +  + ]:       7590 :     return validate_exprs(state, args->defaults, Load, 0) && validate_exprs(state, args->kw_defaults, Load, 1);
     147                 :            : }
     148                 :            : 
     149                 :            : static int
     150                 :      46707 : validate_constant(struct validator *state, PyObject *value)
     151                 :            : {
     152   [ +  +  +  + ]:      46707 :     if (value == Py_None || value == Py_Ellipsis)
     153                 :       4888 :         return 1;
     154                 :            : 
     155         [ +  + ]:      41819 :     if (PyLong_CheckExact(value)
     156         [ +  + ]:      29092 :             || PyFloat_CheckExact(value)
     157         [ +  + ]:      28649 :             || PyComplex_CheckExact(value)
     158         [ +  + ]:      28637 :             || PyBool_Check(value)
     159         [ +  + ]:      26371 :             || PyUnicode_CheckExact(value)
     160         [ +  + ]:        843 :             || PyBytes_CheckExact(value))
     161                 :      41796 :         return 1;
     162                 :            : 
     163   [ +  +  +  + ]:         23 :     if (PyTuple_CheckExact(value) || PyFrozenSet_CheckExact(value)) {
     164         [ -  + ]:         16 :         if (++state->recursion_depth > state->recursion_limit) {
     165                 :          0 :             PyErr_SetString(PyExc_RecursionError,
     166                 :            :                             "maximum recursion depth exceeded during compilation");
     167                 :          0 :             return 0;
     168                 :            :         }
     169                 :            : 
     170                 :         16 :         PyObject *it = PyObject_GetIter(value);
     171         [ +  - ]:         16 :         if (it == NULL)
     172                 :          0 :             return 0;
     173                 :            : 
     174                 :         40 :         while (1) {
     175                 :         56 :             PyObject *item = PyIter_Next(it);
     176         [ +  + ]:         56 :             if (item == NULL) {
     177         [ -  + ]:         14 :                 if (PyErr_Occurred()) {
     178                 :          0 :                     Py_DECREF(it);
     179                 :          0 :                     return 0;
     180                 :            :                 }
     181                 :         14 :                 break;
     182                 :            :             }
     183                 :            : 
     184         [ +  + ]:         42 :             if (!validate_constant(state, item)) {
     185                 :          2 :                 Py_DECREF(it);
     186                 :          2 :                 Py_DECREF(item);
     187                 :          2 :                 return 0;
     188                 :            :             }
     189                 :         40 :             Py_DECREF(item);
     190                 :            :         }
     191                 :            : 
     192                 :         14 :         Py_DECREF(it);
     193                 :         14 :         --state->recursion_depth;
     194                 :         14 :         return 1;
     195                 :            :     }
     196                 :            : 
     197         [ +  - ]:          7 :     if (!PyErr_Occurred()) {
     198                 :          7 :         PyErr_Format(PyExc_TypeError,
     199                 :            :                      "got an invalid type in Constant: %s",
     200                 :            :                      _PyType_Name(Py_TYPE(value)));
     201                 :            :     }
     202                 :          7 :     return 0;
     203                 :            : }
     204                 :            : 
     205                 :            : static int
     206                 :     267487 : validate_expr(struct validator *state, expr_ty exp, expr_context_ty ctx)
     207                 :            : {
     208   [ -  +  -  +  :     267487 :     VALIDATE_POSITIONS(exp);
          -  -  -  +  -  
             -  +  +  -  
                      + ]
     209                 :     267487 :     int ret = -1;
     210         [ -  + ]:     267487 :     if (++state->recursion_depth > state->recursion_limit) {
     211                 :          0 :         PyErr_SetString(PyExc_RecursionError,
     212                 :            :                         "maximum recursion depth exceeded during compilation");
     213                 :          0 :         return 0;
     214                 :            :     }
     215                 :     267487 :     int check_ctx = 1;
     216                 :            :     expr_context_ty actual_ctx;
     217                 :            : 
     218                 :            :     /* First check expression context. */
     219   [ +  +  +  +  :     267487 :     switch (exp->kind) {
                +  +  + ]
     220                 :      35088 :     case Attribute_kind:
     221                 :      35088 :         actual_ctx = exp->v.Attribute.ctx;
     222                 :      35088 :         break;
     223                 :       4948 :     case Subscript_kind:
     224                 :       4948 :         actual_ctx = exp->v.Subscript.ctx;
     225                 :       4948 :         break;
     226                 :        316 :     case Starred_kind:
     227                 :        316 :         actual_ctx = exp->v.Starred.ctx;
     228                 :        316 :         break;
     229                 :     119374 :     case Name_kind:
     230         [ +  + ]:     119374 :         if (!validate_name(exp->v.Name.id)) {
     231                 :          3 :             return 0;
     232                 :            :         }
     233                 :     119371 :         actual_ctx = exp->v.Name.ctx;
     234                 :     119371 :         break;
     235                 :       1489 :     case List_kind:
     236                 :       1489 :         actual_ctx = exp->v.List.ctx;
     237                 :       1489 :         break;
     238                 :       5243 :     case Tuple_kind:
     239                 :       5243 :         actual_ctx = exp->v.Tuple.ctx;
     240                 :       5243 :         break;
     241                 :     101029 :     default:
     242         [ +  + ]:     101029 :         if (ctx != Load) {
     243                 :          1 :             PyErr_Format(PyExc_ValueError, "expression which can't be "
     244                 :            :                          "assigned to in %s context", expr_context_name(ctx));
     245                 :          1 :             return 0;
     246                 :            :         }
     247                 :     101028 :         check_ctx = 0;
     248                 :            :         /* set actual_ctx to prevent gcc warning */
     249                 :     101028 :         actual_ctx = 0;
     250                 :            :     }
     251   [ +  +  +  + ]:     267483 :     if (check_ctx && actual_ctx != ctx) {
     252                 :         86 :         PyErr_Format(PyExc_ValueError, "expression must have %s context but has %s instead",
     253                 :            :                      expr_context_name(ctx), expr_context_name(actual_ctx));
     254                 :         86 :         return 0;
     255                 :            :     }
     256                 :            : 
     257                 :            :     /* Now validate expression. */
     258   [ +  +  +  +  :     267397 :     switch (exp->kind) {
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
             +  +  +  - ]
     259                 :       2070 :     case BoolOp_kind:
     260   [ +  -  +  + ]:       2070 :         if (asdl_seq_LEN(exp->v.BoolOp.values) < 2) {
     261                 :          2 :             PyErr_SetString(PyExc_ValueError, "BoolOp with less than 2 values");
     262                 :          2 :             return 0;
     263                 :            :         }
     264                 :       2068 :         ret = validate_exprs(state, exp->v.BoolOp.values, Load, 0);
     265                 :       2068 :         break;
     266                 :       6682 :     case BinOp_kind:
     267   [ +  -  +  - ]:      13364 :         ret = validate_expr(state, exp->v.BinOp.left, Load) &&
     268                 :       6682 :             validate_expr(state, exp->v.BinOp.right, Load);
     269                 :       6682 :         break;
     270                 :       2999 :     case UnaryOp_kind:
     271                 :       2999 :         ret = validate_expr(state, exp->v.UnaryOp.operand, Load);
     272                 :       2999 :         break;
     273                 :        168 :     case Lambda_kind:
     274   [ +  +  +  + ]:        329 :         ret = validate_arguments(state, exp->v.Lambda.args) &&
     275                 :        161 :             validate_expr(state, exp->v.Lambda.body, Load);
     276                 :        168 :         break;
     277                 :        238 :     case IfExp_kind:
     278         [ +  + ]:        475 :         ret = validate_expr(state, exp->v.IfExp.test, Load) &&
     279   [ +  +  +  + ]:        475 :             validate_expr(state, exp->v.IfExp.body, Load) &&
     280                 :        236 :             validate_expr(state, exp->v.IfExp.orelse, Load);
     281                 :        238 :         break;
     282                 :        625 :     case Dict_kind:
     283   [ +  -  +  -  :        625 :         if (asdl_seq_LEN(exp->v.Dict.keys) != asdl_seq_LEN(exp->v.Dict.values)) {
                   +  + ]
     284                 :          1 :             PyErr_SetString(PyExc_ValueError,
     285                 :            :                             "Dict doesn't have the same number of keys as values");
     286                 :          1 :             return 0;
     287                 :            :         }
     288                 :            :         /* null_ok=1 for keys expressions to allow dict unpacking to work in
     289                 :            :            dict literals, i.e. ``{**{a:b}}`` */
     290   [ +  -  +  + ]:       1248 :         ret = validate_exprs(state, exp->v.Dict.keys, Load, /*null_ok=*/ 1) &&
     291                 :        624 :             validate_exprs(state, exp->v.Dict.values, Load, /*null_ok=*/ 0);
     292                 :        624 :         break;
     293                 :        114 :     case Set_kind:
     294                 :        114 :         ret = validate_exprs(state, exp->v.Set.elts, Load, 0);
     295                 :        114 :         break;
     296                 :            : #define COMP(NAME) \
     297                 :            :         case NAME ## _kind: \
     298                 :            :             ret = validate_comprehension(state, exp->v.NAME.generators) && \
     299                 :            :                 validate_expr(state, exp->v.NAME.elt, Load); \
     300                 :            :             break;
     301   [ +  +  +  + ]:        320 :     COMP(ListComp)
     302   [ +  +  +  + ]:         23 :     COMP(SetComp)
     303   [ +  +  +  + ]:        232 :     COMP(GeneratorExp)
     304                 :            : #undef COMP
     305                 :         37 :     case DictComp_kind:
     306         [ +  + ]:         69 :         ret = validate_comprehension(state, exp->v.DictComp.generators) &&
     307   [ +  +  +  + ]:         69 :             validate_expr(state, exp->v.DictComp.key, Load) &&
     308                 :         31 :             validate_expr(state, exp->v.DictComp.value, Load);
     309                 :         37 :         break;
     310                 :        210 :     case Yield_kind:
     311   [ +  +  +  + ]:        210 :         ret = !exp->v.Yield.value || validate_expr(state, exp->v.Yield.value, Load);
     312                 :        210 :         break;
     313                 :         51 :     case YieldFrom_kind:
     314                 :         51 :         ret = validate_expr(state, exp->v.YieldFrom.value, Load);
     315                 :         51 :         break;
     316                 :         14 :     case Await_kind:
     317                 :         14 :         ret = validate_expr(state, exp->v.Await.value, Load);
     318                 :         14 :         break;
     319                 :       8198 :     case Compare_kind:
     320   [ +  -  +  + ]:       8198 :         if (!asdl_seq_LEN(exp->v.Compare.comparators)) {
     321                 :          1 :             PyErr_SetString(PyExc_ValueError, "Compare with no comparators");
     322                 :          1 :             return 0;
     323                 :            :         }
     324   [ +  -  +  + ]:      16394 :         if (asdl_seq_LEN(exp->v.Compare.comparators) !=
     325         [ +  - ]:       8197 :             asdl_seq_LEN(exp->v.Compare.ops)) {
     326                 :          1 :             PyErr_SetString(PyExc_ValueError, "Compare has a different number "
     327                 :            :                             "of comparators and operands");
     328                 :          1 :             return 0;
     329                 :            :         }
     330   [ +  -  +  - ]:      16392 :         ret = validate_exprs(state, exp->v.Compare.comparators, Load, 0) &&
     331                 :       8196 :             validate_expr(state, exp->v.Compare.left, Load);
     332                 :       8196 :         break;
     333                 :      30125 :     case Call_kind:
     334         [ +  + ]:      60249 :         ret = validate_expr(state, exp->v.Call.func, Load) &&
     335   [ +  +  +  + ]:      60249 :             validate_exprs(state, exp->v.Call.args, Load, 0) &&
     336                 :      30123 :             validate_keywords(state, exp->v.Call.keywords);
     337                 :      30125 :         break;
     338                 :      46665 :     case Constant_kind:
     339         [ +  + ]:      46665 :         if (!validate_constant(state, exp->v.Constant.value)) {
     340                 :          7 :             return 0;
     341                 :            :         }
     342                 :      46658 :         ret = 1;
     343                 :      46658 :         break;
     344                 :        389 :     case JoinedStr_kind:
     345                 :        389 :         ret = validate_exprs(state, exp->v.JoinedStr.values, Load, 0);
     346                 :        389 :         break;
     347                 :        552 :     case FormattedValue_kind:
     348         [ -  + ]:        552 :         if (validate_expr(state, exp->v.FormattedValue.value, Load) == 0)
     349                 :          0 :             return 0;
     350         [ +  + ]:        552 :         if (exp->v.FormattedValue.format_spec) {
     351                 :         19 :             ret = validate_expr(state, exp->v.FormattedValue.format_spec, Load);
     352                 :         19 :             break;
     353                 :            :         }
     354                 :        533 :         ret = 1;
     355                 :        533 :         break;
     356                 :      35087 :     case Attribute_kind:
     357                 :      35087 :         ret = validate_expr(state, exp->v.Attribute.value, Load);
     358                 :      35087 :         break;
     359                 :       4948 :     case Subscript_kind:
     360   [ +  +  +  + ]:       9891 :         ret = validate_expr(state, exp->v.Subscript.slice, Load) &&
     361                 :       4943 :             validate_expr(state, exp->v.Subscript.value, Load);
     362                 :       4948 :         break;
     363                 :        316 :     case Starred_kind:
     364                 :        316 :         ret = validate_expr(state, exp->v.Starred.value, ctx);
     365                 :        316 :         break;
     366                 :       1294 :     case Slice_kind:
     367         [ +  + ]:        774 :         ret = (!exp->v.Slice.lower || validate_expr(state, exp->v.Slice.lower, Load)) &&
     368   [ +  +  +  +  :       3360 :             (!exp->v.Slice.upper || validate_expr(state, exp->v.Slice.upper, Load)) &&
                   +  + ]
     369   [ +  +  +  + ]:       1292 :             (!exp->v.Slice.step || validate_expr(state, exp->v.Slice.step, Load));
     370                 :       1294 :         break;
     371                 :       1489 :     case List_kind:
     372                 :       1489 :         ret = validate_exprs(state, exp->v.List.elts, ctx, 0);
     373                 :       1489 :         break;
     374                 :       5243 :     case Tuple_kind:
     375                 :       5243 :         ret = validate_exprs(state, exp->v.Tuple.elts, ctx, 0);
     376                 :       5243 :         break;
     377                 :         22 :     case NamedExpr_kind:
     378                 :         22 :         ret = validate_expr(state, exp->v.NamedExpr.value, Load);
     379                 :         22 :         break;
     380                 :            :     /* This last case doesn't have any checking. */
     381                 :     119286 :     case Name_kind:
     382                 :     119286 :         ret = 1;
     383                 :     119286 :         break;
     384                 :            :     // No default case so compiler emits warning for unhandled cases
     385                 :            :     }
     386         [ -  + ]:     267385 :     if (ret < 0) {
     387                 :          0 :         PyErr_SetString(PyExc_SystemError, "unexpected expression");
     388                 :          0 :         ret = 0;
     389                 :            :     }
     390                 :     267385 :     state->recursion_depth--;
     391                 :     267385 :     return ret;
     392                 :            : }
     393                 :            : 
     394                 :            : 
     395                 :            : // Note: the ensure_literal_* functions are only used to validate a restricted
     396                 :            : //       set of non-recursive literals that have already been checked with
     397                 :            : //       validate_expr, so they don't accept the validator state
     398                 :            : static int
     399                 :          0 : ensure_literal_number(expr_ty exp, bool allow_real, bool allow_imaginary)
     400                 :            : {
     401                 :            :     assert(exp->kind == Constant_kind);
     402                 :          0 :     PyObject *value = exp->v.Constant.value;
     403   [ #  #  #  # ]:          0 :     return (allow_real && PyFloat_CheckExact(value)) ||
     404   [ #  #  #  #  :          0 :            (allow_real && PyLong_CheckExact(value)) ||
                   #  # ]
     405         [ #  # ]:          0 :            (allow_imaginary && PyComplex_CheckExact(value));
     406                 :            : }
     407                 :            : 
     408                 :            : static int
     409                 :          0 : ensure_literal_negative(expr_ty exp, bool allow_real, bool allow_imaginary)
     410                 :            : {
     411                 :            :     assert(exp->kind == UnaryOp_kind);
     412                 :            :     // Must be negation ...
     413         [ #  # ]:          0 :     if (exp->v.UnaryOp.op != USub) {
     414                 :          0 :         return 0;
     415                 :            :     }
     416                 :            :     // ... of a constant ...
     417                 :          0 :     expr_ty operand = exp->v.UnaryOp.operand;
     418         [ #  # ]:          0 :     if (operand->kind != Constant_kind) {
     419                 :          0 :         return 0;
     420                 :            :     }
     421                 :            :     // ... number
     422                 :          0 :     return ensure_literal_number(operand, allow_real, allow_imaginary);
     423                 :            : }
     424                 :            : 
     425                 :            : static int
     426                 :          0 : ensure_literal_complex(expr_ty exp)
     427                 :            : {
     428                 :            :     assert(exp->kind == BinOp_kind);
     429                 :          0 :     expr_ty left = exp->v.BinOp.left;
     430                 :          0 :     expr_ty right = exp->v.BinOp.right;
     431                 :            :     // Ensure op is addition or subtraction
     432   [ #  #  #  # ]:          0 :     if (exp->v.BinOp.op != Add && exp->v.BinOp.op != Sub) {
     433                 :          0 :         return 0;
     434                 :            :     }
     435                 :            :     // Check LHS is a real number (potentially signed)
     436      [ #  #  # ]:          0 :     switch (left->kind)
     437                 :            :     {
     438                 :          0 :         case Constant_kind:
     439         [ #  # ]:          0 :             if (!ensure_literal_number(left, /*real=*/true, /*imaginary=*/false)) {
     440                 :          0 :                 return 0;
     441                 :            :             }
     442                 :          0 :             break;
     443                 :          0 :         case UnaryOp_kind:
     444         [ #  # ]:          0 :             if (!ensure_literal_negative(left, /*real=*/true, /*imaginary=*/false)) {
     445                 :          0 :                 return 0;
     446                 :            :             }
     447                 :          0 :             break;
     448                 :          0 :         default:
     449                 :          0 :             return 0;
     450                 :            :     }
     451                 :            :     // Check RHS is an imaginary number (no separate sign allowed)
     452         [ #  # ]:          0 :     switch (right->kind)
     453                 :            :     {
     454                 :          0 :         case Constant_kind:
     455         [ #  # ]:          0 :             if (!ensure_literal_number(right, /*real=*/false, /*imaginary=*/true)) {
     456                 :          0 :                 return 0;
     457                 :            :             }
     458                 :          0 :             break;
     459                 :          0 :         default:
     460                 :          0 :             return 0;
     461                 :            :     }
     462                 :          0 :     return 1;
     463                 :            : }
     464                 :            : 
     465                 :            : static int
     466                 :         11 : validate_pattern_match_value(struct validator *state, expr_ty exp)
     467                 :            : {
     468         [ +  + ]:         11 :     if (!validate_expr(state, exp, Load)) {
     469                 :          2 :         return 0;
     470                 :            :     }
     471                 :            : 
     472   [ +  -  -  -  :          9 :     switch (exp->kind)
                   -  + ]
     473                 :            :     {
     474                 :          8 :         case Constant_kind:
     475                 :            :             /* Ellipsis and immutable sequences are not allowed.
     476                 :            :                For True, False and None, MatchSingleton() should
     477                 :            :                be used */
     478         [ -  + ]:          8 :             if (!validate_expr(state, exp, Load)) {
     479                 :          0 :                 return 0;
     480                 :            :             }
     481                 :          8 :             PyObject *literal = exp->v.Constant.value;
     482   [ +  +  +  -  :         13 :             if (PyLong_CheckExact(literal) || PyFloat_CheckExact(literal) ||
                   +  - ]
     483   [ +  -  +  + ]:         15 :                 PyBytes_CheckExact(literal) || PyComplex_CheckExact(literal) ||
     484                 :          5 :                 PyUnicode_CheckExact(literal)) {
     485                 :          5 :                 return 1;
     486                 :            :             }
     487                 :          3 :             PyErr_SetString(PyExc_ValueError,
     488                 :            :                             "unexpected constant inside of a literal pattern");
     489                 :          3 :             return 0;
     490                 :          0 :         case Attribute_kind:
     491                 :            :             // Constants and attribute lookups are always permitted
     492                 :          0 :             return 1;
     493                 :          0 :         case UnaryOp_kind:
     494                 :            :             // Negated numbers are permitted (whether real or imaginary)
     495                 :            :             // Compiler will complain if AST folding doesn't create a constant
     496         [ #  # ]:          0 :             if (ensure_literal_negative(exp, /*real=*/true, /*imaginary=*/true)) {
     497                 :          0 :                 return 1;
     498                 :            :             }
     499                 :          0 :             break;
     500                 :          0 :         case BinOp_kind:
     501                 :            :             // Complex literals are permitted
     502                 :            :             // Compiler will complain if AST folding doesn't create a constant
     503         [ #  # ]:          0 :             if (ensure_literal_complex(exp)) {
     504                 :          0 :                 return 1;
     505                 :            :             }
     506                 :          0 :             break;
     507                 :          0 :         case JoinedStr_kind:
     508                 :            :             // Handled in the later stages
     509                 :          0 :             return 1;
     510                 :          1 :         default:
     511                 :          1 :             break;
     512                 :            :     }
     513                 :          1 :     PyErr_SetString(PyExc_ValueError,
     514                 :            :                     "patterns may only match literals and attribute lookups");
     515                 :          1 :     return 0;
     516                 :            : }
     517                 :            : 
     518                 :            : static int
     519                 :         10 : validate_capture(PyObject *name)
     520                 :            : {
     521         [ +  + ]:         10 :     if (_PyUnicode_EqualToASCIIString(name, "_")) {
     522                 :          3 :         PyErr_Format(PyExc_ValueError, "can't capture name '_' in patterns");
     523                 :          3 :         return 0;
     524                 :            :     }
     525                 :          7 :     return validate_name(name);
     526                 :            : }
     527                 :            : 
     528                 :            : static int
     529                 :         48 : validate_pattern(struct validator *state, pattern_ty p, int star_ok)
     530                 :            : {
     531   [ -  +  -  +  :         48 :     VALIDATE_POSITIONS(p);
          -  -  -  +  -  
             -  +  -  -  
                      + ]
     532                 :         48 :     int ret = -1;
     533         [ -  + ]:         48 :     if (++state->recursion_depth > state->recursion_limit) {
     534                 :          0 :         PyErr_SetString(PyExc_RecursionError,
     535                 :            :                         "maximum recursion depth exceeded during compilation");
     536                 :          0 :         return 0;
     537                 :            :     }
     538   [ +  +  +  +  :         48 :     switch (p->kind) {
             +  +  +  +  
                      - ]
     539                 :         10 :         case MatchValue_kind:
     540                 :         10 :             ret = validate_pattern_match_value(state, p->v.MatchValue.value);
     541                 :         10 :             break;
     542                 :          6 :         case MatchSingleton_kind:
     543   [ +  +  -  + ]:          6 :             ret = p->v.MatchSingleton.value == Py_None || PyBool_Check(p->v.MatchSingleton.value);
     544         [ +  + ]:          6 :             if (!ret) {
     545                 :          5 :                 PyErr_SetString(PyExc_ValueError,
     546                 :            :                                 "MatchSingleton can only contain True, False and None");
     547                 :            :             }
     548                 :          6 :             break;
     549                 :          5 :         case MatchSequence_kind:
     550                 :          5 :             ret = validate_patterns(state, p->v.MatchSequence.patterns, /*star_ok=*/1);
     551                 :          5 :             break;
     552                 :          4 :         case MatchMapping_kind:
     553   [ +  -  +  -  :          4 :             if (asdl_seq_LEN(p->v.MatchMapping.keys) != asdl_seq_LEN(p->v.MatchMapping.patterns)) {
                   +  + ]
     554                 :          1 :                 PyErr_SetString(PyExc_ValueError,
     555                 :            :                                 "MatchMapping doesn't have the same number of keys as patterns");
     556                 :          1 :                 ret = 0;
     557                 :          1 :                 break;
     558                 :            :             }
     559                 :            : 
     560   [ +  -  +  + ]:          3 :             if (p->v.MatchMapping.rest && !validate_capture(p->v.MatchMapping.rest)) {
     561                 :          2 :                 ret = 0;
     562                 :          2 :                 break;
     563                 :            :             }
     564                 :            : 
     565                 :          1 :             asdl_expr_seq *keys = p->v.MatchMapping.keys;
     566   [ +  -  +  - ]:          2 :             for (Py_ssize_t i = 0; i < asdl_seq_LEN(keys); i++) {
     567                 :          2 :                 expr_ty key = asdl_seq_GET(keys, i);
     568         [ +  + ]:          2 :                 if (key->kind == Constant_kind) {
     569                 :          1 :                     PyObject *literal = key->v.Constant.value;
     570   [ +  -  +  - ]:          1 :                     if (literal == Py_None || PyBool_Check(literal)) {
     571                 :            :                         /* validate_pattern_match_value will ensure the key
     572                 :            :                            doesn't contain True, False and None but it is
     573                 :            :                            syntactically valid, so we will pass those on in
     574                 :            :                            a special case. */
     575                 :          1 :                         continue;
     576                 :            :                     }
     577                 :            :                 }
     578         [ +  - ]:          1 :                 if (!validate_pattern_match_value(state, key)) {
     579                 :          1 :                     ret = 0;
     580                 :          1 :                     break;
     581                 :            :                 }
     582                 :            :             }
     583                 :            : 
     584                 :          1 :             ret = validate_patterns(state, p->v.MatchMapping.patterns, /*star_ok=*/0);
     585                 :          1 :             break;
     586                 :         10 :         case MatchClass_kind:
     587   [ +  -  +  -  :         10 :             if (asdl_seq_LEN(p->v.MatchClass.kwd_attrs) != asdl_seq_LEN(p->v.MatchClass.kwd_patterns)) {
                   +  + ]
     588                 :          2 :                 PyErr_SetString(PyExc_ValueError,
     589                 :            :                                 "MatchClass doesn't have the same number of keyword attributes as patterns");
     590                 :          2 :                 ret = 0;
     591                 :          2 :                 break;
     592                 :            :             }
     593         [ -  + ]:          8 :             if (!validate_expr(state, p->v.MatchClass.cls, Load)) {
     594                 :          0 :                 ret = 0;
     595                 :          0 :                 break;
     596                 :            :             }
     597                 :            : 
     598                 :          8 :             expr_ty cls = p->v.MatchClass.cls;
     599                 :            :             while (1) {
     600         [ +  + ]:         13 :                 if (cls->kind == Name_kind) {
     601                 :          7 :                     break;
     602                 :            :                 }
     603         [ +  + ]:          6 :                 else if (cls->kind == Attribute_kind) {
     604                 :          5 :                     cls = cls->v.Attribute.value;
     605                 :          5 :                     continue;
     606                 :            :                 }
     607                 :            :                 else {
     608                 :          1 :                     PyErr_SetString(PyExc_ValueError,
     609                 :            :                                     "MatchClass cls field can only contain Name or Attribute nodes.");
     610                 :          1 :                     ret = 0;
     611                 :          1 :                     break;
     612                 :            :                 }
     613                 :            :             }
     614                 :            : 
     615   [ +  -  +  + ]:          8 :             for (Py_ssize_t i = 0; i < asdl_seq_LEN(p->v.MatchClass.kwd_attrs); i++) {
     616                 :          1 :                 PyObject *identifier = asdl_seq_GET(p->v.MatchClass.kwd_attrs, i);
     617         [ +  - ]:          1 :                 if (!validate_name(identifier)) {
     618                 :          1 :                     ret = 0;
     619                 :          1 :                     break;
     620                 :            :                 }
     621                 :            :             }
     622                 :            : 
     623         [ +  + ]:          8 :             if (!validate_patterns(state, p->v.MatchClass.patterns, /*star_ok=*/0)) {
     624                 :          2 :                 ret = 0;
     625                 :          2 :                 break;
     626                 :            :             }
     627                 :            : 
     628                 :          6 :             ret = validate_patterns(state, p->v.MatchClass.kwd_patterns, /*star_ok=*/0);
     629                 :          6 :             break;
     630                 :          4 :         case MatchStar_kind:
     631         [ +  + ]:          4 :             if (!star_ok) {
     632                 :          2 :                 PyErr_SetString(PyExc_ValueError, "can't use MatchStar here");
     633                 :          2 :                 ret = 0;
     634                 :          2 :                 break;
     635                 :            :             }
     636   [ +  -  -  + ]:          2 :             ret = p->v.MatchStar.name == NULL || validate_capture(p->v.MatchStar.name);
     637                 :          2 :             break;
     638                 :          6 :         case MatchAs_kind:
     639   [ +  +  +  + ]:          6 :             if (p->v.MatchAs.name && !validate_capture(p->v.MatchAs.name)) {
     640                 :          2 :                 ret = 0;
     641                 :          2 :                 break;
     642                 :            :             }
     643         [ +  - ]:          4 :             if (p->v.MatchAs.pattern == NULL) {
     644                 :          4 :                 ret = 1;
     645                 :            :             }
     646         [ #  # ]:          0 :             else if (p->v.MatchAs.name == NULL) {
     647                 :          0 :                 PyErr_SetString(PyExc_ValueError,
     648                 :            :                                 "MatchAs must specify a target name if a pattern is given");
     649                 :          0 :                 ret = 0;
     650                 :            :             }
     651                 :            :             else {
     652                 :          0 :                 ret = validate_pattern(state, p->v.MatchAs.pattern, /*star_ok=*/0);
     653                 :            :             }
     654                 :          4 :             break;
     655                 :          3 :         case MatchOr_kind:
     656   [ +  -  +  + ]:          3 :             if (asdl_seq_LEN(p->v.MatchOr.patterns) < 2) {
     657                 :          2 :                 PyErr_SetString(PyExc_ValueError,
     658                 :            :                                 "MatchOr requires at least 2 patterns");
     659                 :          2 :                 ret = 0;
     660                 :          2 :                 break;
     661                 :            :             }
     662                 :          1 :             ret = validate_patterns(state, p->v.MatchOr.patterns, /*star_ok=*/0);
     663                 :          1 :             break;
     664                 :            :     // No default case, so the compiler will emit a warning if new pattern
     665                 :            :     // kinds are added without being handled here
     666                 :            :     }
     667         [ -  + ]:         48 :     if (ret < 0) {
     668                 :          0 :         PyErr_SetString(PyExc_SystemError, "unexpected pattern");
     669                 :          0 :         ret = 0;
     670                 :            :     }
     671                 :         48 :     state->recursion_depth--;
     672                 :         48 :     return ret;
     673                 :            : }
     674                 :            : 
     675                 :            : static int
     676                 :      47468 : _validate_nonempty_seq(asdl_seq *seq, const char *what, const char *owner)
     677                 :            : {
     678   [ +  -  +  + ]:      47468 :     if (asdl_seq_LEN(seq))
     679                 :      47451 :         return 1;
     680                 :         17 :     PyErr_Format(PyExc_ValueError, "empty %s on %s", what, owner);
     681                 :         17 :     return 0;
     682                 :            : }
     683                 :            : #define validate_nonempty_seq(seq, what, owner) _validate_nonempty_seq((asdl_seq*)seq, what, owner)
     684                 :            : 
     685                 :            : static int
     686                 :      21076 : validate_assignlist(struct validator *state, asdl_expr_seq *targets, expr_context_ty ctx)
     687                 :            : {
     688   [ +  +  +  +  :      42150 :     return validate_nonempty_seq(targets, "targets", ctx == Del ? "Delete" : "Assign") &&
                   +  + ]
     689                 :      21074 :         validate_exprs(state, targets, ctx, 0);
     690                 :            : }
     691                 :            : 
     692                 :            : static int
     693                 :      24552 : validate_body(struct validator *state, asdl_stmt_seq *body, const char *owner)
     694                 :            : {
     695   [ +  +  +  + ]:      24552 :     return validate_nonempty_seq(body, "body", owner) && validate_stmts(state, body);
     696                 :            : }
     697                 :            : 
     698                 :            : static int
     699                 :      69956 : validate_stmt(struct validator *state, stmt_ty stmt)
     700                 :            : {
     701   [ +  +  +  +  :      69956 :     VALIDATE_POSITIONS(stmt);
          -  +  +  +  +  
             -  +  +  +  
                      + ]
     702                 :      69946 :     int ret = -1;
     703                 :            :     Py_ssize_t i;
     704         [ -  + ]:      69946 :     if (++state->recursion_depth > state->recursion_limit) {
     705                 :          0 :         PyErr_SetString(PyExc_RecursionError,
     706                 :            :                         "maximum recursion depth exceeded during compilation");
     707                 :          0 :         return 0;
     708                 :            :     }
     709   [ +  +  +  +  :      69946 :     switch (stmt->kind) {
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
                   +  - ]
     710                 :       7392 :     case FunctionDef_kind:
     711         [ +  + ]:      14783 :         ret = validate_body(state, stmt->v.FunctionDef.body, "FunctionDef") &&
     712         [ +  + ]:      14775 :             validate_arguments(state, stmt->v.FunctionDef.args) &&
     713         [ +  + ]:      22167 :             validate_exprs(state, stmt->v.FunctionDef.decorator_list, Load, 0) &&
     714   [ +  +  +  + ]:       7439 :             (!stmt->v.FunctionDef.returns ||
     715                 :         56 :              validate_expr(state, stmt->v.FunctionDef.returns, Load));
     716                 :       7392 :         break;
     717                 :        829 :     case ClassDef_kind:
     718         [ +  + ]:       1656 :         ret = validate_body(state, stmt->v.ClassDef.body, "ClassDef") &&
     719         [ +  + ]:       1653 :             validate_exprs(state, stmt->v.ClassDef.bases, Load, 0) &&
     720   [ +  +  +  + ]:       2482 :             validate_keywords(state, stmt->v.ClassDef.keywords) &&
     721                 :        825 :             validate_exprs(state, stmt->v.ClassDef.decorator_list, Load, 0);
     722                 :        829 :         break;
     723                 :       7068 :     case Return_kind:
     724   [ +  +  +  - ]:       7068 :         ret = !stmt->v.Return.value || validate_expr(state, stmt->v.Return.value, Load);
     725                 :       7068 :         break;
     726                 :        223 :     case Delete_kind:
     727                 :        223 :         ret = validate_assignlist(state, stmt->v.Delete.targets, Del);
     728                 :        223 :         break;
     729                 :      20853 :     case Assign_kind:
     730   [ +  +  +  + ]:      41701 :         ret = validate_assignlist(state, stmt->v.Assign.targets, Store) &&
     731                 :      20848 :             validate_expr(state, stmt->v.Assign.value, Load);
     732                 :      20853 :         break;
     733                 :        860 :     case AugAssign_kind:
     734   [ +  +  +  + ]:       1719 :         ret = validate_expr(state, stmt->v.AugAssign.target, Store) &&
     735                 :        859 :             validate_expr(state, stmt->v.AugAssign.value, Load);
     736                 :        860 :         break;
     737                 :         37 :     case AnnAssign_kind:
     738         [ +  + ]:         37 :         if (stmt->v.AnnAssign.target->kind != Name_kind &&
     739         [ -  + ]:          9 :             stmt->v.AnnAssign.simple) {
     740                 :          0 :             PyErr_SetString(PyExc_TypeError,
     741                 :            :                             "AnnAssign with simple non-Name target");
     742                 :          0 :             return 0;
     743                 :            :         }
     744                 :         37 :         ret = validate_expr(state, stmt->v.AnnAssign.target, Store) &&
     745   [ +  +  +  - ]:         48 :                (!stmt->v.AnnAssign.value ||
     746   [ +  -  +  - ]:         85 :                 validate_expr(state, stmt->v.AnnAssign.value, Load)) &&
     747                 :         37 :                validate_expr(state, stmt->v.AnnAssign.annotation, Load);
     748                 :         37 :         break;
     749                 :       1394 :     case For_kind:
     750         [ +  + ]:       2787 :         ret = validate_expr(state, stmt->v.For.target, Store) &&
     751         [ +  + ]:       2785 :             validate_expr(state, stmt->v.For.iter, Load) &&
     752   [ +  +  +  + ]:       4179 :             validate_body(state, stmt->v.For.body, "For") &&
     753                 :       1390 :             validate_stmts(state, stmt->v.For.orelse);
     754                 :       1394 :         break;
     755                 :          6 :     case AsyncFor_kind:
     756         [ +  - ]:         12 :         ret = validate_expr(state, stmt->v.AsyncFor.target, Store) &&
     757         [ +  - ]:         12 :             validate_expr(state, stmt->v.AsyncFor.iter, Load) &&
     758   [ +  -  +  - ]:         18 :             validate_body(state, stmt->v.AsyncFor.body, "AsyncFor") &&
     759                 :          6 :             validate_stmts(state, stmt->v.AsyncFor.orelse);
     760                 :          6 :         break;
     761                 :        445 :     case While_kind:
     762         [ +  + ]:        889 :         ret = validate_expr(state, stmt->v.While.test, Load) &&
     763   [ +  +  +  + ]:        889 :             validate_body(state, stmt->v.While.body, "While") &&
     764                 :        443 :             validate_stmts(state, stmt->v.While.orelse);
     765                 :        445 :         break;
     766                 :      11158 :     case If_kind:
     767         [ +  + ]:      22315 :         ret = validate_expr(state, stmt->v.If.test, Load) &&
     768   [ +  +  +  + ]:      22315 :             validate_body(state, stmt->v.If.body, "If") &&
     769                 :      11155 :             validate_stmts(state, stmt->v.If.orelse);
     770                 :      11158 :         break;
     771                 :        384 :     case With_kind:
     772         [ +  + ]:        384 :         if (!validate_nonempty_seq(stmt->v.With.items, "items", "With"))
     773                 :          1 :             return 0;
     774   [ +  -  +  + ]:        786 :         for (i = 0; i < asdl_seq_LEN(stmt->v.With.items); i++) {
     775                 :        405 :             withitem_ty item = asdl_seq_GET(stmt->v.With.items, i);
     776         [ +  + ]:        405 :             if (!validate_expr(state, item->context_expr, Load) ||
     777   [ +  +  +  + ]:        404 :                 (item->optional_vars && !validate_expr(state, item->optional_vars, Store)))
     778                 :          2 :                 return 0;
     779                 :            :         }
     780                 :        381 :         ret = validate_body(state, stmt->v.With.body, "With");
     781                 :        381 :         break;
     782                 :          9 :     case AsyncWith_kind:
     783         [ -  + ]:          9 :         if (!validate_nonempty_seq(stmt->v.AsyncWith.items, "items", "AsyncWith"))
     784                 :          0 :             return 0;
     785   [ +  -  +  + ]:         21 :         for (i = 0; i < asdl_seq_LEN(stmt->v.AsyncWith.items); i++) {
     786                 :         12 :             withitem_ty item = asdl_seq_GET(stmt->v.AsyncWith.items, i);
     787         [ +  - ]:         12 :             if (!validate_expr(state, item->context_expr, Load) ||
     788   [ +  +  -  + ]:         12 :                 (item->optional_vars && !validate_expr(state, item->optional_vars, Store)))
     789                 :          0 :                 return 0;
     790                 :            :         }
     791                 :          9 :         ret = validate_body(state, stmt->v.AsyncWith.body, "AsyncWith");
     792                 :          9 :         break;
     793                 :         29 :     case Match_kind:
     794         [ +  - ]:         29 :         if (!validate_expr(state, stmt->v.Match.subject, Load)
     795         [ -  + ]:         29 :             || !validate_nonempty_seq(stmt->v.Match.cases, "cases", "Match")) {
     796                 :          0 :             return 0;
     797                 :            :         }
     798   [ +  -  +  + ]:         39 :         for (i = 0; i < asdl_seq_LEN(stmt->v.Match.cases); i++) {
     799                 :         33 :             match_case_ty m = asdl_seq_GET(stmt->v.Match.cases, i);
     800         [ +  + ]:         33 :             if (!validate_pattern(state, m->pattern, /*star_ok=*/0)
     801   [ +  +  +  - ]:         10 :                 || (m->guard && !validate_expr(state, m->guard, Load))
     802         [ -  + ]:         10 :                 || !validate_body(state, m->body, "match_case")) {
     803                 :         23 :                 return 0;
     804                 :            :             }
     805                 :            :         }
     806                 :          6 :         ret = 1;
     807                 :          6 :         break;
     808                 :       2311 :     case Raise_kind:
     809         [ +  + ]:       2311 :         if (stmt->v.Raise.exc) {
     810         [ +  + ]:       4293 :             ret = validate_expr(state, stmt->v.Raise.exc, Load) &&
     811   [ +  +  +  + ]:       2146 :                 (!stmt->v.Raise.cause || validate_expr(state, stmt->v.Raise.cause, Load));
     812                 :       2147 :             break;
     813                 :            :         }
     814         [ +  + ]:        164 :         if (stmt->v.Raise.cause) {
     815                 :          1 :             PyErr_SetString(PyExc_ValueError, "Raise with cause but no exception");
     816                 :          1 :             return 0;
     817                 :            :         }
     818                 :        163 :         ret = 1;
     819                 :        163 :         break;
     820                 :       1470 :     case Try_kind:
     821         [ +  + ]:       1470 :         if (!validate_body(state, stmt->v.Try.body, "Try"))
     822                 :          2 :             return 0;
     823   [ +  -  +  + ]:       1468 :         if (!asdl_seq_LEN(stmt->v.Try.handlers) &&
     824   [ +  -  +  + ]:        150 :             !asdl_seq_LEN(stmt->v.Try.finalbody)) {
     825                 :          1 :             PyErr_SetString(PyExc_ValueError, "Try has neither except handlers nor finalbody");
     826                 :          1 :             return 0;
     827                 :            :         }
     828   [ +  -  +  + ]:       1467 :         if (!asdl_seq_LEN(stmt->v.Try.handlers) &&
     829   [ +  -  +  + ]:        149 :             asdl_seq_LEN(stmt->v.Try.orelse)) {
     830                 :          1 :             PyErr_SetString(PyExc_ValueError, "Try has orelse but no except handlers");
     831                 :          1 :             return 0;
     832                 :            :         }
     833   [ +  -  +  + ]:       2862 :         for (i = 0; i < asdl_seq_LEN(stmt->v.Try.handlers); i++) {
     834                 :       1398 :             excepthandler_ty handler = asdl_seq_GET(stmt->v.Try.handlers, i);
     835   [ -  +  -  +  :       1398 :             VALIDATE_POSITIONS(handler);
          -  -  -  +  -  
             -  +  +  -  
                      + ]
     836   [ +  +  +  + ]:       2703 :             if ((handler->v.ExceptHandler.type &&
     837         [ +  + ]:       2702 :                  !validate_expr(state, handler->v.ExceptHandler.type, Load)) ||
     838                 :       1397 :                 !validate_body(state, handler->v.ExceptHandler.body, "ExceptHandler"))
     839                 :          2 :                 return 0;
     840                 :            :         }
     841   [ +  +  +  + ]:       1634 :         ret = (!asdl_seq_LEN(stmt->v.Try.finalbody) ||
     842         [ +  - ]:       3098 :                 validate_stmts(state, stmt->v.Try.finalbody)) &&
     843   [ +  -  +  +  :       1641 :             (!asdl_seq_LEN(stmt->v.Try.orelse) ||
                   +  + ]
     844                 :        178 :              validate_stmts(state, stmt->v.Try.orelse));
     845                 :       1464 :         break;
     846                 :         14 :     case TryStar_kind:
     847         [ +  + ]:         14 :         if (!validate_body(state, stmt->v.TryStar.body, "TryStar"))
     848                 :          2 :             return 0;
     849   [ +  -  +  + ]:         12 :         if (!asdl_seq_LEN(stmt->v.TryStar.handlers) &&
     850   [ +  -  +  + ]:          2 :             !asdl_seq_LEN(stmt->v.TryStar.finalbody)) {
     851                 :          1 :             PyErr_SetString(PyExc_ValueError, "TryStar has neither except handlers nor finalbody");
     852                 :          1 :             return 0;
     853                 :            :         }
     854   [ +  -  +  + ]:         11 :         if (!asdl_seq_LEN(stmt->v.TryStar.handlers) &&
     855   [ +  -  +  - ]:          1 :             asdl_seq_LEN(stmt->v.TryStar.orelse)) {
     856                 :          1 :             PyErr_SetString(PyExc_ValueError, "TryStar has orelse but no except handlers");
     857                 :          1 :             return 0;
     858                 :            :         }
     859   [ +  -  +  + ]:         19 :         for (i = 0; i < asdl_seq_LEN(stmt->v.TryStar.handlers); i++) {
     860                 :         11 :             excepthandler_ty handler = asdl_seq_GET(stmt->v.TryStar.handlers, i);
     861   [ +  +  +  + ]:         19 :             if ((handler->v.ExceptHandler.type &&
     862         [ +  + ]:         18 :                  !validate_expr(state, handler->v.ExceptHandler.type, Load)) ||
     863                 :         10 :                 !validate_body(state, handler->v.ExceptHandler.body, "ExceptHandler"))
     864                 :          2 :                 return 0;
     865                 :            :         }
     866   [ +  +  +  + ]:         10 :         ret = (!asdl_seq_LEN(stmt->v.TryStar.finalbody) ||
     867         [ +  - ]:         18 :                 validate_stmts(state, stmt->v.TryStar.finalbody)) &&
     868   [ +  -  +  +  :         10 :             (!asdl_seq_LEN(stmt->v.TryStar.orelse) ||
                   +  + ]
     869                 :          3 :              validate_stmts(state, stmt->v.TryStar.orelse));
     870                 :          8 :         break;
     871                 :        224 :     case Assert_kind:
     872         [ +  + ]:        447 :         ret = validate_expr(state, stmt->v.Assert.test, Load) &&
     873   [ +  +  +  + ]:        223 :             (!stmt->v.Assert.msg || validate_expr(state, stmt->v.Assert.msg, Load));
     874                 :        224 :         break;
     875                 :        961 :     case Import_kind:
     876                 :        961 :         ret = validate_nonempty_seq(stmt->v.Import.names, "names", "Import");
     877                 :        961 :         break;
     878                 :        371 :     case ImportFrom_kind:
     879         [ +  + ]:        371 :         if (stmt->v.ImportFrom.level < 0) {
     880                 :          1 :             PyErr_SetString(PyExc_ValueError, "Negative ImportFrom level");
     881                 :          1 :             return 0;
     882                 :            :         }
     883                 :        370 :         ret = validate_nonempty_seq(stmt->v.ImportFrom.names, "names", "ImportFrom");
     884                 :        370 :         break;
     885                 :         66 :     case Global_kind:
     886                 :         66 :         ret = validate_nonempty_seq(stmt->v.Global.names, "names", "Global");
     887                 :         66 :         break;
     888                 :         21 :     case Nonlocal_kind:
     889                 :         21 :         ret = validate_nonempty_seq(stmt->v.Nonlocal.names, "names", "Nonlocal");
     890                 :         21 :         break;
     891                 :      12376 :     case Expr_kind:
     892                 :      12376 :         ret = validate_expr(state, stmt->v.Expr.value, Load);
     893                 :      12376 :         break;
     894                 :         41 :     case AsyncFunctionDef_kind:
     895         [ +  - ]:         82 :         ret = validate_body(state, stmt->v.AsyncFunctionDef.body, "AsyncFunctionDef") &&
     896         [ +  - ]:         82 :             validate_arguments(state, stmt->v.AsyncFunctionDef.args) &&
     897         [ +  - ]:        123 :             validate_exprs(state, stmt->v.AsyncFunctionDef.decorator_list, Load, 0) &&
     898   [ -  +  -  - ]:         41 :             (!stmt->v.AsyncFunctionDef.returns ||
     899                 :          0 :              validate_expr(state, stmt->v.AsyncFunctionDef.returns, Load));
     900                 :         41 :         break;
     901                 :       1404 :     case Pass_kind:
     902                 :            :     case Break_kind:
     903                 :            :     case Continue_kind:
     904                 :       1404 :         ret = 1;
     905                 :       1404 :         break;
     906                 :            :     // No default case so compiler emits warning for unhandled cases
     907                 :            :     }
     908         [ -  + ]:      69906 :     if (ret < 0) {
     909                 :          0 :         PyErr_SetString(PyExc_SystemError, "unexpected statement");
     910                 :          0 :         ret = 0;
     911                 :            :     }
     912                 :      69906 :     state->recursion_depth--;
     913                 :      69906 :     return ret;
     914                 :            : }
     915                 :            : 
     916                 :            : static int
     917                 :      38459 : validate_stmts(struct validator *state, asdl_stmt_seq *seq)
     918                 :            : {
     919                 :            :     Py_ssize_t i;
     920   [ +  -  +  + ]:     108234 :     for (i = 0; i < asdl_seq_LEN(seq); i++) {
     921                 :      69957 :         stmt_ty stmt = asdl_seq_GET(seq, i);
     922         [ +  + ]:      69957 :         if (stmt) {
     923         [ +  + ]:      69956 :             if (!validate_stmt(state, stmt))
     924                 :        181 :                 return 0;
     925                 :            :         }
     926                 :            :         else {
     927                 :          1 :             PyErr_SetString(PyExc_ValueError,
     928                 :            :                             "None disallowed in statement list");
     929                 :          1 :             return 0;
     930                 :            :         }
     931                 :            :     }
     932                 :      38277 :     return 1;
     933                 :            : }
     934                 :            : 
     935                 :            : static int
     936                 :      94827 : validate_exprs(struct validator *state, asdl_expr_seq *exprs, expr_context_ty ctx, int null_ok)
     937                 :            : {
     938                 :            :     Py_ssize_t i;
     939   [ +  -  +  + ]:     192911 :     for (i = 0; i < asdl_seq_LEN(exprs); i++) {
     940                 :      98117 :         expr_ty expr = asdl_seq_GET(exprs, i);
     941         [ +  + ]:      98117 :         if (expr) {
     942         [ +  + ]:      98052 :             if (!validate_expr(state, expr, ctx))
     943                 :         21 :                 return 0;
     944                 :            :         }
     945         [ +  + ]:         65 :         else if (!null_ok) {
     946                 :         12 :             PyErr_SetString(PyExc_ValueError,
     947                 :            :                             "None disallowed in expression list");
     948                 :         12 :             return 0;
     949                 :            :         }
     950                 :            : 
     951                 :            :     }
     952                 :      94794 :     return 1;
     953                 :            : }
     954                 :            : 
     955                 :            : static int
     956                 :         21 : validate_patterns(struct validator *state, asdl_pattern_seq *patterns, int star_ok)
     957                 :            : {
     958                 :            :     Py_ssize_t i;
     959   [ +  -  +  + ]:         28 :     for (i = 0; i < asdl_seq_LEN(patterns); i++) {
     960                 :         15 :         pattern_ty pattern = asdl_seq_GET(patterns, i);
     961         [ +  + ]:         15 :         if (!validate_pattern(state, pattern, star_ok)) {
     962                 :          8 :             return 0;
     963                 :            :         }
     964                 :            :     }
     965                 :         13 :     return 1;
     966                 :            : }
     967                 :            : 
     968                 :            : 
     969                 :            : /* See comments in symtable.c. */
     970                 :            : #define COMPILER_STACK_FRAME_SCALE 3
     971                 :            : 
     972                 :            : int
     973                 :        679 : _PyAST_Validate(mod_ty mod)
     974                 :            : {
     975                 :        679 :     int res = -1;
     976                 :            :     struct validator state;
     977                 :            :     PyThreadState *tstate;
     978                 :        679 :     int recursion_limit = Py_GetRecursionLimit();
     979                 :            :     int starting_recursion_depth;
     980                 :            : 
     981                 :            :     /* Setup recursion depth check counters */
     982                 :        679 :     tstate = _PyThreadState_GET();
     983         [ -  + ]:        679 :     if (!tstate) {
     984                 :          0 :         return 0;
     985                 :            :     }
     986                 :            :     /* Be careful here to prevent overflow. */
     987                 :        679 :     int recursion_depth = tstate->recursion_limit - tstate->recursion_remaining;
     988                 :        679 :     starting_recursion_depth = (recursion_depth< INT_MAX / COMPILER_STACK_FRAME_SCALE) ?
     989         [ +  - ]:        679 :         recursion_depth * COMPILER_STACK_FRAME_SCALE : recursion_depth;
     990                 :        679 :     state.recursion_depth = starting_recursion_depth;
     991                 :        679 :     state.recursion_limit = (recursion_limit < INT_MAX / COMPILER_STACK_FRAME_SCALE) ?
     992         [ +  - ]:        679 :         recursion_limit * COMPILER_STACK_FRAME_SCALE : recursion_limit;
     993                 :            : 
     994   [ +  +  +  -  :        679 :     switch (mod->kind) {
                      - ]
     995                 :        568 :     case Module_kind:
     996                 :        568 :         res = validate_stmts(&state, mod->v.Module.body);
     997                 :        568 :         break;
     998                 :          2 :     case Interactive_kind:
     999                 :          2 :         res = validate_stmts(&state, mod->v.Interactive.body);
    1000                 :          2 :         break;
    1001                 :        109 :     case Expression_kind:
    1002                 :        109 :         res = validate_expr(&state, mod->v.Expression.body, Load);
    1003                 :        109 :         break;
    1004                 :          0 :     case FunctionType_kind:
    1005   [ #  #  #  # ]:          0 :         res = validate_exprs(&state, mod->v.FunctionType.argtypes, Load, /*null_ok=*/0) &&
    1006                 :          0 :               validate_expr(&state, mod->v.FunctionType.returns, Load);
    1007                 :          0 :         break;
    1008                 :            :     // No default case so compiler emits warning for unhandled cases
    1009                 :            :     }
    1010                 :            : 
    1011         [ -  + ]:        679 :     if (res < 0) {
    1012                 :          0 :         PyErr_SetString(PyExc_SystemError, "impossible module node");
    1013                 :          0 :         return 0;
    1014                 :            :     }
    1015                 :            : 
    1016                 :            :     /* Check that the recursion depth counting balanced correctly */
    1017   [ +  +  -  + ]:        679 :     if (res && state.recursion_depth != starting_recursion_depth) {
    1018                 :          0 :         PyErr_Format(PyExc_SystemError,
    1019                 :            :             "AST validator recursion depth mismatch (before=%d, after=%d)",
    1020                 :            :             starting_recursion_depth, state.recursion_depth);
    1021                 :          0 :         return 0;
    1022                 :            :     }
    1023                 :        679 :     return res;
    1024                 :            : }
    1025                 :            : 
    1026                 :            : PyObject *
    1027                 :     936126 : _PyAST_GetDocString(asdl_stmt_seq *body)
    1028                 :            : {
    1029   [ +  +  -  + ]:     936126 :     if (!asdl_seq_LEN(body)) {
    1030                 :       1358 :         return NULL;
    1031                 :            :     }
    1032                 :     934768 :     stmt_ty st = asdl_seq_GET(body, 0);
    1033         [ +  + ]:     934768 :     if (st->kind != Expr_kind) {
    1034                 :     646079 :         return NULL;
    1035                 :            :     }
    1036                 :     288689 :     expr_ty e = st->v.Expr.value;
    1037   [ +  +  +  + ]:     288689 :     if (e->kind == Constant_kind && PyUnicode_CheckExact(e->v.Constant.value)) {
    1038                 :     202396 :         return e->v.Constant.value;
    1039                 :            :     }
    1040                 :      86293 :     return NULL;
    1041                 :            : }

Generated by: LCOV version 1.14