https://github.com/python/cpython/commit/754e7c9b5187fcad22acf7555479603f173a4a09
commit: 754e7c9b5187fcad22acf7555479603f173a4a09
branch: main
author: Bénédikt Tran <[email protected]>
committer: pablogsal <[email protected]>
date: 2025-06-10T01:08:30+01:00
summary:
gh-133157: remove usage of `_Py_NO_SANITIZE_UNDEFINED` in `Parser/pegen.c`
(#134048)
files:
M Parser/parser.c
M Parser/pegen.c
M Parser/pegen.h
M Tools/peg_generator/pegen/c_generator.py
diff --git a/Parser/parser.c b/Parser/parser.c
index 82311b4f40eebf..ee0aeb4e1875cb 100644
--- a/Parser/parser.c
+++ b/Parser/parser.c
@@ -1679,7 +1679,7 @@ simple_stmt_rule(Parser *p)
D(fprintf(stderr, "%*c> simple_stmt[%d-%d]: %s\n", p->level, ' ',
_mark, p->mark, "&('import' | 'from') import_stmt"));
stmt_ty import_stmt_var;
if (
- _PyPegen_lookahead(1, (void *(*)(Parser *)) _tmp_5_rule, p)
+ _PyPegen_lookahead(1, _tmp_5_rule, p)
&&
(import_stmt_var = import_stmt_rule(p)) // import_stmt
)
@@ -1917,7 +1917,7 @@ compound_stmt_rule(Parser *p)
D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ',
_mark, p->mark, "&('def' | '@' | 'async') function_def"));
stmt_ty function_def_var;
if (
- _PyPegen_lookahead(1, (void *(*)(Parser *)) _tmp_6_rule, p)
+ _PyPegen_lookahead(1, _tmp_6_rule, p)
&&
(function_def_var = function_def_rule(p)) // function_def
)
@@ -1959,7 +1959,7 @@ compound_stmt_rule(Parser *p)
D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ',
_mark, p->mark, "&('class' | '@') class_def"));
stmt_ty class_def_var;
if (
- _PyPegen_lookahead(1, (void *(*)(Parser *)) _tmp_7_rule, p)
+ _PyPegen_lookahead(1, _tmp_7_rule, p)
&&
(class_def_var = class_def_rule(p)) // class_def
)
@@ -1980,7 +1980,7 @@ compound_stmt_rule(Parser *p)
D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ',
_mark, p->mark, "&('with' | 'async') with_stmt"));
stmt_ty with_stmt_var;
if (
- _PyPegen_lookahead(1, (void *(*)(Parser *)) _tmp_8_rule, p)
+ _PyPegen_lookahead(1, _tmp_8_rule, p)
&&
(with_stmt_var = with_stmt_rule(p)) // with_stmt
)
@@ -2001,7 +2001,7 @@ compound_stmt_rule(Parser *p)
D(fprintf(stderr, "%*c> compound_stmt[%d-%d]: %s\n", p->level, ' ',
_mark, p->mark, "&('for' | 'async') for_stmt"));
stmt_ty for_stmt_var;
if (
- _PyPegen_lookahead(1, (void *(*)(Parser *)) _tmp_9_rule, p)
+ _PyPegen_lookahead(1, _tmp_9_rule, p)
&&
(for_stmt_var = for_stmt_rule(p)) // for_stmt
)
@@ -3234,7 +3234,7 @@ del_stmt_rule(Parser *p)
&&
(a = del_targets_rule(p)) // del_targets
&&
- _PyPegen_lookahead(1, (void *(*)(Parser *)) _tmp_16_rule, p)
+ _PyPegen_lookahead(1, _tmp_16_rule, p)
)
{
D(fprintf(stderr, "%*c+ del_stmt[%d-%d]: %s succeeded!\n",
p->level, ' ', _mark, p->mark, "'del' del_targets &(';' | NEWLINE)"));
@@ -6877,7 +6877,7 @@ with_item_rule(Parser *p)
&&
(t = star_target_rule(p)) // star_target
&&
- _PyPegen_lookahead(1, (void *(*)(Parser *)) _tmp_36_rule, p)
+ _PyPegen_lookahead(1, _tmp_36_rule, p)
)
{
D(fprintf(stderr, "%*c+ with_item[%d-%d]: %s succeeded!\n",
p->level, ' ', _mark, p->mark, "expression 'as' star_target &(',' | ')' |
':')"));
@@ -8466,7 +8466,7 @@ literal_pattern_rule(Parser *p)
if (
(value = signed_number_rule(p)) // signed_number
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) _tmp_42_rule, p)
+ _PyPegen_lookahead(0, _tmp_42_rule, p)
)
{
D(fprintf(stderr, "%*c+ literal_pattern[%d-%d]: %s succeeded!\n",
p->level, ' ', _mark, p->mark, "signed_number !('+' | '-')"));
@@ -8700,7 +8700,7 @@ literal_expr_rule(Parser *p)
if (
(signed_number_var = signed_number_rule(p)) // signed_number
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) _tmp_42_rule, p)
+ _PyPegen_lookahead(0, _tmp_42_rule, p)
)
{
D(fprintf(stderr, "%*c+ literal_expr[%d-%d]: %s succeeded!\n",
p->level, ' ', _mark, p->mark, "signed_number !('+' | '-')"));
@@ -8738,7 +8738,7 @@ literal_expr_rule(Parser *p)
D(fprintf(stderr, "%*c> literal_expr[%d-%d]: %s\n", p->level, ' ',
_mark, p->mark, "&(STRING | FSTRING_START | TSTRING_START) strings"));
expr_ty strings_var;
if (
- _PyPegen_lookahead(1, (void *(*)(Parser *)) _tmp_43_rule, p)
+ _PyPegen_lookahead(1, _tmp_43_rule, p)
&&
(strings_var = strings_rule(p)) // strings
)
@@ -9302,7 +9302,7 @@ pattern_capture_target_rule(Parser *p)
&&
(name = _PyPegen_name_token(p)) // NAME
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) _tmp_44_rule, p)
+ _PyPegen_lookahead(0, _tmp_44_rule, p)
)
{
D(fprintf(stderr, "%*c+ pattern_capture_target[%d-%d]: %s
succeeded!\n", p->level, ' ', _mark, p->mark, "!\"_\" NAME !('.' | '(' |
'=')"));
@@ -9417,7 +9417,7 @@ value_pattern_rule(Parser *p)
if (
(attr = attr_rule(p)) // attr
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) _tmp_44_rule, p)
+ _PyPegen_lookahead(0, _tmp_44_rule, p)
)
{
D(fprintf(stderr, "%*c+ value_pattern[%d-%d]: %s succeeded!\n",
p->level, ' ', _mark, p->mark, "attr !('.' | '(' | '=')"));
@@ -15070,7 +15070,7 @@ atom_rule(Parser *p)
D(fprintf(stderr, "%*c> atom[%d-%d]: %s\n", p->level, ' ', _mark,
p->mark, "&(STRING | FSTRING_START | TSTRING_START) strings"));
expr_ty strings_var;
if (
- _PyPegen_lookahead(1, (void *(*)(Parser *)) _tmp_43_rule, p)
+ _PyPegen_lookahead(1, _tmp_43_rule, p)
&&
(strings_var = strings_rule(p)) // strings
)
@@ -19099,7 +19099,7 @@ target_with_star_atom_rule(Parser *p)
&&
(b = _PyPegen_name_token(p)) // NAME
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) t_lookahead_rule, p)
+ _PyPegen_lookahead(0, t_lookahead_rule, p)
)
{
D(fprintf(stderr, "%*c+ target_with_star_atom[%d-%d]: %s
succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME
!t_lookahead"));
@@ -19143,7 +19143,7 @@ target_with_star_atom_rule(Parser *p)
&&
(_literal_1 = _PyPegen_expect_token(p, 10)) // token=']'
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) t_lookahead_rule, p)
+ _PyPegen_lookahead(0, t_lookahead_rule, p)
)
{
D(fprintf(stderr, "%*c+ target_with_star_atom[%d-%d]: %s
succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']'
!t_lookahead"));
@@ -19490,7 +19490,7 @@ single_subscript_attribute_target_rule(Parser *p)
&&
(b = _PyPegen_name_token(p)) // NAME
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) t_lookahead_rule, p)
+ _PyPegen_lookahead(0, t_lookahead_rule, p)
)
{
D(fprintf(stderr, "%*c+ single_subscript_attribute_target[%d-%d]:
%s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '.' NAME
!t_lookahead"));
@@ -19534,7 +19534,7 @@ single_subscript_attribute_target_rule(Parser *p)
&&
(_literal_1 = _PyPegen_expect_token(p, 10)) // token=']'
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) t_lookahead_rule, p)
+ _PyPegen_lookahead(0, t_lookahead_rule, p)
)
{
D(fprintf(stderr, "%*c+ single_subscript_attribute_target[%d-%d]:
%s succeeded!\n", p->level, ' ', _mark, p->mark, "t_primary '[' slices ']'
!t_lookahead"));
@@ -19644,7 +19644,7 @@ t_primary_raw(Parser *p)
&&
(b = _PyPegen_name_token(p)) // NAME
&&
- _PyPegen_lookahead(1, (void *(*)(Parser *)) t_lookahead_rule, p)
+ _PyPegen_lookahead(1, t_lookahead_rule, p)
)
{
D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n",
p->level, ' ', _mark, p->mark, "t_primary '.' NAME &t_lookahead"));
@@ -19688,7 +19688,7 @@ t_primary_raw(Parser *p)
&&
(_literal_1 = _PyPegen_expect_token(p, 10)) // token=']'
&&
- _PyPegen_lookahead(1, (void *(*)(Parser *)) t_lookahead_rule, p)
+ _PyPegen_lookahead(1, t_lookahead_rule, p)
)
{
D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n",
p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' &t_lookahead"));
@@ -19726,7 +19726,7 @@ t_primary_raw(Parser *p)
&&
(b = genexp_rule(p)) // genexp
&&
- _PyPegen_lookahead(1, (void *(*)(Parser *)) t_lookahead_rule, p)
+ _PyPegen_lookahead(1, t_lookahead_rule, p)
)
{
D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n",
p->level, ' ', _mark, p->mark, "t_primary genexp &t_lookahead"));
@@ -19770,7 +19770,7 @@ t_primary_raw(Parser *p)
&&
(_literal_1 = _PyPegen_expect_token(p, 8)) // token=')'
&&
- _PyPegen_lookahead(1, (void *(*)(Parser *)) t_lookahead_rule, p)
+ _PyPegen_lookahead(1, t_lookahead_rule, p)
)
{
D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n",
p->level, ' ', _mark, p->mark, "t_primary '(' arguments? ')' &t_lookahead"));
@@ -19805,7 +19805,7 @@ t_primary_raw(Parser *p)
if (
(a = atom_rule(p)) // atom
&&
- _PyPegen_lookahead(1, (void *(*)(Parser *)) t_lookahead_rule, p)
+ _PyPegen_lookahead(1, t_lookahead_rule, p)
)
{
D(fprintf(stderr, "%*c+ t_primary[%d-%d]: %s succeeded!\n",
p->level, ' ', _mark, p->mark, "atom &t_lookahead"));
@@ -19995,7 +19995,7 @@ del_target_rule(Parser *p)
&&
(b = _PyPegen_name_token(p)) // NAME
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) t_lookahead_rule, p)
+ _PyPegen_lookahead(0, t_lookahead_rule, p)
)
{
D(fprintf(stderr, "%*c+ del_target[%d-%d]: %s succeeded!\n",
p->level, ' ', _mark, p->mark, "t_primary '.' NAME !t_lookahead"));
@@ -20039,7 +20039,7 @@ del_target_rule(Parser *p)
&&
(_literal_1 = _PyPegen_expect_token(p, 10)) // token=']'
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) t_lookahead_rule, p)
+ _PyPegen_lookahead(0, t_lookahead_rule, p)
)
{
D(fprintf(stderr, "%*c+ del_target[%d-%d]: %s succeeded!\n",
p->level, ' ', _mark, p->mark, "t_primary '[' slices ']' !t_lookahead"));
@@ -20527,7 +20527,7 @@ func_type_comment_rule(Parser *p)
&&
(t = _PyPegen_expect_token(p, TYPE_COMMENT)) //
token='TYPE_COMMENT'
&&
- _PyPegen_lookahead(1, (void *(*)(Parser *)) _tmp_104_rule, p)
+ _PyPegen_lookahead(1, _tmp_104_rule, p)
)
{
D(fprintf(stderr, "%*c+ func_type_comment[%d-%d]: %s
succeeded!\n", p->level, ' ', _mark, p->mark, "NEWLINE TYPE_COMMENT &(NEWLINE
INDENT)"));
@@ -20721,7 +20721,7 @@ invalid_arguments_rule(Parser *p)
&&
(b = _PyPegen_expect_token(p, 22)) // token='='
&&
- _PyPegen_lookahead(1, (void *(*)(Parser *)) _tmp_110_rule, p)
+ _PyPegen_lookahead(1, _tmp_110_rule, p)
)
{
D(fprintf(stderr, "%*c+ invalid_arguments[%d-%d]: %s
succeeded!\n", p->level, ' ', _mark, p->mark, "[(args ',')] NAME '=' &(',' |
')')"));
@@ -20919,7 +20919,7 @@ invalid_kwarg_rule(Parser *p)
expr_ty a;
Token * b;
if (
- _PyPegen_lookahead(0, (void *(*)(Parser *)) _tmp_112_rule, p)
+ _PyPegen_lookahead(0, _tmp_112_rule, p)
&&
(a = expression_rule(p)) // expression
&&
@@ -21294,7 +21294,7 @@ invalid_expression_rule(Parser *p)
expr_ty a;
expr_ty b;
if (
- _PyPegen_lookahead(0, (void *(*)(Parser *)) _tmp_114_rule, p)
+ _PyPegen_lookahead(0, _tmp_114_rule, p)
&&
(a = disjunction_rule(p)) // disjunction
&&
@@ -21330,7 +21330,7 @@ invalid_expression_rule(Parser *p)
&&
(b = disjunction_rule(p)) // disjunction
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) _tmp_115_rule, p)
+ _PyPegen_lookahead(0, _tmp_115_rule, p)
)
{
D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s
succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction
!('else' | ':')"));
@@ -21365,7 +21365,7 @@ invalid_expression_rule(Parser *p)
&&
(_keyword_1 = _PyPegen_expect_token(p, 690)) // token='else'
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) expression_rule, p)
+ _PyPegen_lookahead_for_expr(0, expression_rule, p)
)
{
D(fprintf(stderr, "%*c+ invalid_expression[%d-%d]: %s
succeeded!\n", p->level, ' ', _mark, p->mark, "disjunction 'if' disjunction
'else' !expression"));
@@ -21555,7 +21555,7 @@ invalid_named_expression_rule(Parser *p)
&&
(b = bitwise_or_rule(p)) // bitwise_or
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) _tmp_117_rule, p)
+ _PyPegen_lookahead(0, _tmp_117_rule, p)
)
{
D(fprintf(stderr, "%*c+ invalid_named_expression[%d-%d]: %s
succeeded!\n", p->level, ' ', _mark, p->mark, "NAME '=' bitwise_or !('=' |
':=')"));
@@ -21581,7 +21581,7 @@ invalid_named_expression_rule(Parser *p)
Token * b;
expr_ty bitwise_or_var;
if (
- _PyPegen_lookahead(0, (void *(*)(Parser *)) _tmp_118_rule, p)
+ _PyPegen_lookahead(0, _tmp_118_rule, p)
&&
(a = bitwise_or_rule(p)) // bitwise_or
&&
@@ -21589,7 +21589,7 @@ invalid_named_expression_rule(Parser *p)
&&
(bitwise_or_var = bitwise_or_rule(p)) // bitwise_or
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) _tmp_117_rule, p)
+ _PyPegen_lookahead(0, _tmp_117_rule, p)
)
{
D(fprintf(stderr, "%*c+ invalid_named_expression[%d-%d]: %s
succeeded!\n", p->level, ' ', _mark, p->mark, "!(list | tuple | genexp | 'True'
| 'None' | 'False') bitwise_or '=' bitwise_or !('=' | ':=')"));
@@ -22499,7 +22499,7 @@ invalid_default_rule(Parser *p)
if (
(a = _PyPegen_expect_token(p, 22)) // token='='
&&
- _PyPegen_lookahead(1, (void *(*)(Parser *)) _tmp_125_rule, p)
+ _PyPegen_lookahead(1, _tmp_125_rule, p)
)
{
D(fprintf(stderr, "%*c+ invalid_default[%d-%d]: %s succeeded!\n",
p->level, ' ', _mark, p->mark, "'=' &(')' | ',')"));
@@ -23448,7 +23448,7 @@ invalid_with_item_rule(Parser *p)
&&
(a = expression_rule(p)) // expression
&&
- _PyPegen_lookahead(1, (void *(*)(Parser *)) _tmp_36_rule, p)
+ _PyPegen_lookahead(1, _tmp_36_rule, p)
)
{
D(fprintf(stderr, "%*c+ invalid_with_item[%d-%d]: %s
succeeded!\n", p->level, ' ', _mark, p->mark, "expression 'as' expression &(','
| ')' | ':')"));
@@ -23760,7 +23760,7 @@ invalid_dotted_as_name_rule(Parser *p)
&&
(_keyword = _PyPegen_expect_token(p, 684)) // token='as'
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) _tmp_138_rule, p)
+ _PyPegen_lookahead(0, _tmp_138_rule, p)
&&
(a = expression_rule(p)) // expression
)
@@ -23811,7 +23811,7 @@ invalid_import_from_as_name_rule(Parser *p)
&&
(_keyword = _PyPegen_expect_token(p, 684)) // token='as'
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) _tmp_138_rule, p)
+ _PyPegen_lookahead(0, _tmp_138_rule, p)
&&
(a = expression_rule(p)) // expression
)
@@ -24181,7 +24181,7 @@ invalid_try_stmt_rule(Parser *p)
&&
(block_var = block_rule(p)) // block
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) _tmp_143_rule, p)
+ _PyPegen_lookahead(0, _tmp_143_rule, p)
)
{
D(fprintf(stderr, "%*c+ invalid_try_stmt[%d-%d]: %s succeeded!\n",
p->level, ' ', _mark, p->mark, "'try' ':' block !('except' | 'finally')"));
@@ -25973,7 +25973,7 @@ invalid_double_starred_kvpairs_rule(Parser *p)
&&
(a = _PyPegen_expect_token(p, 11)) // token=':'
&&
- _PyPegen_lookahead(1, (void *(*)(Parser *)) _tmp_148_rule, p)
+ _PyPegen_lookahead(1, _tmp_148_rule, p)
)
{
D(fprintf(stderr, "%*c+ invalid_double_starred_kvpairs[%d-%d]: %s
succeeded!\n", p->level, ' ', _mark, p->mark, "expression ':' &('}' | ',')"));
@@ -26083,7 +26083,7 @@ invalid_kvpair_rule(Parser *p)
&&
(a = _PyPegen_expect_token(p, 11)) // token=':'
&&
- _PyPegen_lookahead(1, (void *(*)(Parser *)) _tmp_148_rule, p)
+ _PyPegen_lookahead(1, _tmp_148_rule, p)
)
{
D(fprintf(stderr, "%*c+ invalid_kvpair[%d-%d]: %s succeeded!\n",
p->level, ' ', _mark, p->mark, "expression ':' &('}' | ',')"));
@@ -26342,7 +26342,7 @@ invalid_fstring_replacement_field_rule(Parser *p)
if (
(_literal = _PyPegen_expect_token(p, 25)) // token='{'
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) annotated_rhs_rule, p)
+ _PyPegen_lookahead_for_expr(0, annotated_rhs_rule, p)
)
{
D(fprintf(stderr, "%*c+ invalid_fstring_replacement_field[%d-%d]:
%s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' !annotated_rhs"));
@@ -26371,7 +26371,7 @@ invalid_fstring_replacement_field_rule(Parser *p)
&&
(annotated_rhs_var = annotated_rhs_rule(p)) // annotated_rhs
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) _tmp_149_rule, p)
+ _PyPegen_lookahead(0, _tmp_149_rule, p)
)
{
D(fprintf(stderr, "%*c+ invalid_fstring_replacement_field[%d-%d]:
%s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' annotated_rhs !('=' | '!'
| ':' | '}')"));
@@ -26403,7 +26403,7 @@ invalid_fstring_replacement_field_rule(Parser *p)
&&
(_literal_1 = _PyPegen_expect_token(p, 22)) // token='='
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) _tmp_150_rule, p)
+ _PyPegen_lookahead(0, _tmp_150_rule, p)
)
{
D(fprintf(stderr, "%*c+ invalid_fstring_replacement_field[%d-%d]:
%s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' annotated_rhs '=' !('!' |
':' | '}')"));
@@ -26469,7 +26469,7 @@ invalid_fstring_replacement_field_rule(Parser *p)
&&
(_opt_var_1 = _tmp_151_rule(p), !p->error_indicator) // ['!' NAME]
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) _tmp_152_rule, p)
+ _PyPegen_lookahead(0, _tmp_152_rule, p)
)
{
D(fprintf(stderr, "%*c+ invalid_fstring_replacement_field[%d-%d]:
%s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' annotated_rhs '='? ['!'
NAME] !(':' | '}')"));
@@ -26594,7 +26594,7 @@ invalid_fstring_conversion_character_rule(Parser *p)
if (
(_literal = _PyPegen_expect_token(p, 54)) // token='!'
&&
- _PyPegen_lookahead(1, (void *(*)(Parser *)) _tmp_152_rule, p)
+ _PyPegen_lookahead(1, _tmp_152_rule, p)
)
{
D(fprintf(stderr, "%*c+
invalid_fstring_conversion_character[%d-%d]: %s succeeded!\n", p->level, ' ',
_mark, p->mark, "'!' &(':' | '}')"));
@@ -26620,7 +26620,7 @@ invalid_fstring_conversion_character_rule(Parser *p)
if (
(_literal = _PyPegen_expect_token(p, 54)) // token='!'
&&
- _PyPegen_lookahead_with_name(0, _PyPegen_name_token, p)
+ _PyPegen_lookahead_for_expr(0, _PyPegen_name_token, p)
)
{
D(fprintf(stderr, "%*c+
invalid_fstring_conversion_character[%d-%d]: %s succeeded!\n", p->level, ' ',
_mark, p->mark, "'!' !NAME"));
@@ -26784,7 +26784,7 @@ invalid_tstring_replacement_field_rule(Parser *p)
if (
(_literal = _PyPegen_expect_token(p, 25)) // token='{'
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) annotated_rhs_rule, p)
+ _PyPegen_lookahead_for_expr(0, annotated_rhs_rule, p)
)
{
D(fprintf(stderr, "%*c+ invalid_tstring_replacement_field[%d-%d]:
%s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' !annotated_rhs"));
@@ -26813,7 +26813,7 @@ invalid_tstring_replacement_field_rule(Parser *p)
&&
(annotated_rhs_var = annotated_rhs_rule(p)) // annotated_rhs
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) _tmp_149_rule, p)
+ _PyPegen_lookahead(0, _tmp_149_rule, p)
)
{
D(fprintf(stderr, "%*c+ invalid_tstring_replacement_field[%d-%d]:
%s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' annotated_rhs !('=' | '!'
| ':' | '}')"));
@@ -26845,7 +26845,7 @@ invalid_tstring_replacement_field_rule(Parser *p)
&&
(_literal_1 = _PyPegen_expect_token(p, 22)) // token='='
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) _tmp_150_rule, p)
+ _PyPegen_lookahead(0, _tmp_150_rule, p)
)
{
D(fprintf(stderr, "%*c+ invalid_tstring_replacement_field[%d-%d]:
%s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' annotated_rhs '=' !('!' |
':' | '}')"));
@@ -26911,7 +26911,7 @@ invalid_tstring_replacement_field_rule(Parser *p)
&&
(_opt_var_1 = _tmp_151_rule(p), !p->error_indicator) // ['!' NAME]
&&
- _PyPegen_lookahead(0, (void *(*)(Parser *)) _tmp_152_rule, p)
+ _PyPegen_lookahead(0, _tmp_152_rule, p)
)
{
D(fprintf(stderr, "%*c+ invalid_tstring_replacement_field[%d-%d]:
%s succeeded!\n", p->level, ' ', _mark, p->mark, "'{' annotated_rhs '='? ['!'
NAME] !(':' | '}')"));
@@ -27036,7 +27036,7 @@ invalid_tstring_conversion_character_rule(Parser *p)
if (
(_literal = _PyPegen_expect_token(p, 54)) // token='!'
&&
- _PyPegen_lookahead(1, (void *(*)(Parser *)) _tmp_152_rule, p)
+ _PyPegen_lookahead(1, _tmp_152_rule, p)
)
{
D(fprintf(stderr, "%*c+
invalid_tstring_conversion_character[%d-%d]: %s succeeded!\n", p->level, ' ',
_mark, p->mark, "'!' &(':' | '}')"));
@@ -27062,7 +27062,7 @@ invalid_tstring_conversion_character_rule(Parser *p)
if (
(_literal = _PyPegen_expect_token(p, 54)) // token='!'
&&
- _PyPegen_lookahead_with_name(0, _PyPegen_name_token, p)
+ _PyPegen_lookahead_for_expr(0, _PyPegen_name_token, p)
)
{
D(fprintf(stderr, "%*c+
invalid_tstring_conversion_character[%d-%d]: %s succeeded!\n", p->level, ' ',
_mark, p->mark, "'!' !NAME"));
@@ -37501,7 +37501,7 @@ _tmp_168_rule(Parser *p)
D(fprintf(stderr, "%*c> _tmp_168[%d-%d]: %s\n", p->level, ' ', _mark,
p->mark, "!STRING expression_without_invalid"));
expr_ty expression_without_invalid_var;
if (
- _PyPegen_lookahead(0, (void *(*)(Parser *)) _PyPegen_string_token,
p)
+ _PyPegen_lookahead(0, _PyPegen_string_token, p)
&&
(expression_without_invalid_var =
expression_without_invalid_rule(p)) // expression_without_invalid
)
diff --git a/Parser/pegen.c b/Parser/pegen.c
index 81aad47010181c..0919ff417f1916 100644
--- a/Parser/pegen.c
+++ b/Parser/pegen.c
@@ -379,44 +379,34 @@ _PyPegen_is_memoized(Parser *p, int type, void *pres)
return 0;
}
-int
-_PyPegen_lookahead_with_name(int positive, expr_ty (func)(Parser *), Parser *p)
-{
- int mark = p->mark;
- void *res = func(p);
- p->mark = mark;
- return (res != NULL) == positive;
-}
-
-int
-_PyPegen_lookahead_with_string(int positive, expr_ty (func)(Parser *, const
char*), Parser *p, const char* arg)
-{
- int mark = p->mark;
- void *res = func(p, arg);
- p->mark = mark;
- return (res != NULL) == positive;
-}
-
-int
-_PyPegen_lookahead_with_int(int positive, Token *(func)(Parser *, int), Parser
*p, int arg)
-{
- int mark = p->mark;
- void *res = func(p, arg);
- p->mark = mark;
- return (res != NULL) == positive;
-}
-
-// gh-111178: Use _Py_NO_SANITIZE_UNDEFINED to disable sanitizer checks on
-// undefined behavior (UBsan) in this function, rather than changing 'func'
-// callback API.
-int _Py_NO_SANITIZE_UNDEFINED
-_PyPegen_lookahead(int positive, void *(func)(Parser *), Parser *p)
-{
- int mark = p->mark;
- void *res = func(p);
- p->mark = mark;
- return (res != NULL) == positive;
-}
+#define LOOKAHEAD1(NAME, RES_TYPE) \
+ int \
+ NAME (int positive, RES_TYPE (func)(Parser *), Parser *p) \
+ { \
+ int mark = p->mark; \
+ void *res = func(p); \
+ p->mark = mark; \
+ return (res != NULL) == positive; \
+ }
+
+LOOKAHEAD1(_PyPegen_lookahead, void *)
+LOOKAHEAD1(_PyPegen_lookahead_for_expr, expr_ty)
+LOOKAHEAD1(_PyPegen_lookahead_for_stmt, stmt_ty)
+#undef LOOKAHEAD1
+
+#define LOOKAHEAD2(NAME, RES_TYPE, T) \
+ int \
+ NAME (int positive, RES_TYPE (func)(Parser *, T), Parser *p, T arg) \
+ { \
+ int mark = p->mark; \
+ void *res = func(p, arg); \
+ p->mark = mark; \
+ return (res != NULL) == positive; \
+ }
+
+LOOKAHEAD2(_PyPegen_lookahead_with_int, Token *, int)
+LOOKAHEAD2(_PyPegen_lookahead_with_string, expr_ty, const char *)
+#undef LOOKAHEAD2
Token *
_PyPegen_expect_token(Parser *p, int type)
diff --git a/Parser/pegen.h b/Parser/pegen.h
index 1862fd7407ec3c..804f931871aec8 100644
--- a/Parser/pegen.h
+++ b/Parser/pegen.h
@@ -145,10 +145,11 @@ int _PyPegen_insert_memo(Parser *p, int mark, int type,
void *node);
int _PyPegen_update_memo(Parser *p, int mark, int type, void *node);
int _PyPegen_is_memoized(Parser *p, int type, void *pres);
-int _PyPegen_lookahead_with_name(int, expr_ty (func)(Parser *), Parser *);
-int _PyPegen_lookahead_with_int(int, Token *(func)(Parser *, int), Parser *,
int);
-int _PyPegen_lookahead_with_string(int , expr_ty (func)(Parser *, const
char*), Parser *, const char*);
int _PyPegen_lookahead(int, void *(func)(Parser *), Parser *);
+int _PyPegen_lookahead_for_expr(int, expr_ty (func)(Parser *), Parser *);
+int _PyPegen_lookahead_for_stmt(int, stmt_ty (func)(Parser *), Parser *);
+int _PyPegen_lookahead_with_int(int, Token *(func)(Parser *, int), Parser *,
int);
+int _PyPegen_lookahead_with_string(int, expr_ty (func)(Parser *, const char*),
Parser *, const char*);
Token *_PyPegen_expect_token(Parser *p, int type);
void* _PyPegen_expect_forced_result(Parser *p, void* result, const char*
expected);
diff --git a/Tools/peg_generator/pegen/c_generator.py
b/Tools/peg_generator/pegen/c_generator.py
index 09c5651f24a3bb..04f66eec1a0154 100644
--- a/Tools/peg_generator/pegen/c_generator.py
+++ b/Tools/peg_generator/pegen/c_generator.py
@@ -214,33 +214,47 @@ def visit_NamedItem(self, node: NamedItem) ->
FunctionCall:
call.assigned_variable_type = node.type
return call
+ def assert_no_undefined_behavior(
+ self, call: FunctionCall, wrapper: str, expected_rtype: str | None,
+ ) -> None:
+ if call.return_type != expected_rtype:
+ raise RuntimeError(
+ f"{call.function} return type is incompatible with {wrapper}: "
+ f"expect: {expected_rtype}, actual: {call.return_type}"
+ )
+
def lookahead_call_helper(self, node: Lookahead, positive: int) ->
FunctionCall:
call = self.generate_call(node.node)
- if call.nodetype == NodeTypes.NAME_TOKEN:
- return FunctionCall(
- function=f"_PyPegen_lookahead_with_name",
- arguments=[positive, call.function, *call.arguments],
- return_type="int",
- )
+ comment = None
+ if call.nodetype is NodeTypes.NAME_TOKEN:
+ function = "_PyPegen_lookahead_for_expr"
+ self.assert_no_undefined_behavior(call, function, "expr_ty")
+ elif call.nodetype is NodeTypes.STRING_TOKEN:
+ # _PyPegen_string_token() returns 'void *' instead of 'Token *';
+ # in addition, the overall function call would return 'expr_ty'.
+ assert call.function == "_PyPegen_string_token"
+ function = "_PyPegen_lookahead"
+ self.assert_no_undefined_behavior(call, function, "expr_ty")
elif call.nodetype == NodeTypes.SOFT_KEYWORD:
- return FunctionCall(
- function=f"_PyPegen_lookahead_with_string",
- arguments=[positive, call.function, *call.arguments],
- return_type="int",
- )
+ function = "_PyPegen_lookahead_with_string"
+ self.assert_no_undefined_behavior(call, function, "expr_ty")
elif call.nodetype in {NodeTypes.GENERIC_TOKEN, NodeTypes.KEYWORD}:
- return FunctionCall(
- function=f"_PyPegen_lookahead_with_int",
- arguments=[positive, call.function, *call.arguments],
- return_type="int",
- comment=f"token={node.node}",
- )
+ function = "_PyPegen_lookahead_with_int"
+ self.assert_no_undefined_behavior(call, function, "Token *")
+ comment = f"token={node.node}"
+ elif call.return_type == "expr_ty":
+ function = "_PyPegen_lookahead_for_expr"
+ elif call.return_type == "stmt_ty":
+ function = "_PyPegen_lookahead_for_stmt"
else:
- return FunctionCall(
- function=f"_PyPegen_lookahead",
- arguments=[positive, f"(void *(*)(Parser *)) {call.function}",
*call.arguments],
- return_type="int",
- )
+ function = "_PyPegen_lookahead"
+ self.assert_no_undefined_behavior(call, function, None)
+ return FunctionCall(
+ function=function,
+ arguments=[positive, call.function, *call.arguments],
+ return_type="int",
+ comment=comment,
+ )
def visit_PositiveLookahead(self, node: PositiveLookahead) -> FunctionCall:
return self.lookahead_call_helper(node, 1)
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]