@@ -686,7 +686,8 @@ static node *get_rawdocstring(node *);
686686static int get_ref_type (struct compiling * , char * );
687687
688688/* symtable operations */
689- static int symtable_build (struct compiling * , node * );
689+ static struct symtable * symtable_build (node * , PyFutureFeatures * ,
690+ const char * filename );
690691static int symtable_load_symbols (struct compiling * );
691692static struct symtable * symtable_init (void );
692693static void symtable_enter_scope (struct symtable * , char * , int , int );
@@ -4250,26 +4251,12 @@ PyNode_CompileSymtable(node *n, const char *filename)
42504251 ff = PyNode_Future (n , filename );
42514252 if (ff == NULL )
42524253 return NULL ;
4253-
4254- st = symtable_init ();
4254+ st = symtable_build (n , ff , filename );
42554255 if (st == NULL ) {
42564256 PyObject_FREE ((void * )ff );
42574257 return NULL ;
42584258 }
4259- st -> st_future = ff ;
4260- symtable_enter_scope (st , TOP , TYPE (n ), n -> n_lineno );
4261- if (st -> st_errors > 0 )
4262- goto fail ;
4263- symtable_node (st , n );
4264- if (st -> st_errors > 0 )
4265- goto fail ;
4266-
42674259 return st ;
4268- fail :
4269- PyObject_FREE ((void * )ff );
4270- st -> st_future = NULL ;
4271- PySymtable_Free (st );
4272- return NULL ;
42734260}
42744261
42754262static PyCodeObject *
@@ -4319,10 +4306,14 @@ jcompile(node *n, const char *filename, struct compiling *base,
43194306 sc .c_future -> ff_features = merged ;
43204307 flags -> cf_flags = merged ;
43214308 }
4322- if (symtable_build (& sc , n ) < 0 ) {
4309+ sc .c_symtable = symtable_build (n , sc .c_future , sc .c_filename );
4310+ if (sc .c_symtable == NULL ) {
43234311 com_free (& sc );
43244312 return NULL ;
43254313 }
4314+ /* reset symbol table for second pass */
4315+ sc .c_symtable -> st_nscopes = 1 ;
4316+ sc .c_symtable -> st_pass = 2 ;
43264317 }
43274318 co = NULL ;
43284319 if (symtable_load_symbols (& sc ) < 0 ) {
@@ -4443,6 +4434,15 @@ get_ref_type(struct compiling *c, char *name)
44434434static int
44444435issue_warning (const char * msg , const char * filename , int lineno )
44454436{
4437+ if (PyErr_Occurred ()) {
4438+ /* This can happen because symtable_node continues
4439+ processing even after raising a SyntaxError.
4440+ Calling PyErr_WarnExplicit now would clobber the
4441+ pending exception; instead we fail and let that
4442+ exception propagate.
4443+ */
4444+ return -1 ;
4445+ }
44464446 if (PyErr_WarnExplicit (PyExc_SyntaxWarning , msg , filename ,
44474447 lineno , NULL , NULL ) < 0 ) {
44484448 if (PyErr_ExceptionMatches (PyExc_SyntaxWarning )) {
@@ -4466,23 +4466,37 @@ symtable_warn(struct symtable *st, char *msg)
44664466
44674467/* Helper function for setting lineno and filename */
44684468
4469- static int
4470- symtable_build (struct compiling * c , node * n )
4469+ static struct symtable *
4470+ symtable_build (node * n , PyFutureFeatures * ff , const char * filename )
44714471{
4472- if ((c -> c_symtable = symtable_init ()) == NULL )
4473- return -1 ;
4474- c -> c_symtable -> st_future = c -> c_future ;
4475- c -> c_symtable -> st_filename = c -> c_filename ;
4476- symtable_enter_scope (c -> c_symtable , TOP , TYPE (n ), n -> n_lineno );
4477- if (c -> c_symtable -> st_errors > 0 )
4478- return -1 ;
4479- symtable_node (c -> c_symtable , n );
4480- if (c -> c_symtable -> st_errors > 0 )
4481- return -1 ;
4482- /* reset for second pass */
4483- c -> c_symtable -> st_nscopes = 1 ;
4484- c -> c_symtable -> st_pass = 2 ;
4485- return 0 ;
4472+ struct symtable * st ;
4473+
4474+ st = symtable_init ();
4475+ if (st == NULL )
4476+ return NULL ;
4477+ st -> st_future = ff ;
4478+ st -> st_filename = filename ;
4479+ symtable_enter_scope (st , TOP , TYPE (n ), n -> n_lineno );
4480+ if (st -> st_errors > 0 )
4481+ goto fail ;
4482+ symtable_node (st , n );
4483+ if (st -> st_errors > 0 )
4484+ goto fail ;
4485+ return st ;
4486+ fail :
4487+ if (!PyErr_Occurred ()) {
4488+ /* This could happen because after a syntax error is
4489+ detected, the symbol-table-building continues for
4490+ a while, and PyErr_Clear() might erroneously be
4491+ called during that process. One such case has been
4492+ fixed, but there might be more (now or later).
4493+ */
4494+ PyErr_SetString (PyExc_SystemError , "lost exception" );
4495+ }
4496+ st -> st_future = NULL ;
4497+ st -> st_filename = NULL ;
4498+ PySymtable_Free (st );
4499+ return NULL ;
44864500}
44874501
44884502static int
0 commit comments