Coverage Report

Created: 2022-07-08 09:39

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