[Python-checkins] python/dist/src/Python compile.c,2.290,2.291

jhylton@users.sourceforge.net jhylton@users.sourceforge.net
2003年7月15日 13:23:28 -0700


Update of /cvsroot/python/python/dist/src/Python
In directory sc8-pr-cvs1:/tmp/cvs-serv31506
Modified Files:
	compile.c 
Log Message:
SF patch 763201: handling of SyntaxErrors in symbol table build
Fixes for three related bugs, including errors that caused a script to
be ignored without printing an error message. The key problem was a bad
interaction between syntax warnings and syntax errors. If an
exception was already set when a warning was issued, the warning could
clobber the exception.
The PyErr_Occurred() check in issue_warning() isn't entirely
satisfying (the caller should know whether there was already an
error), but a better solution isn't immediately obvious.
Bug fix candidate.
Index: compile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v
retrieving revision 2.290
retrieving revision 2.291
diff -C2 -d -r2.290 -r2.291
*** compile.c	20 Jun 2003 16:13:17 -0000	2.290
--- compile.c	15 Jul 2003 20:23:26 -0000	2.291
***************
*** 687,691 ****
 
 /* symtable operations */
! static int symtable_build(struct compiling *, node *);
 static int symtable_load_symbols(struct compiling *);
 static struct symtable *symtable_init(void);
--- 687,692 ----
 
 /* symtable operations */
! static struct symtable *symtable_build(node *, PyFutureFeatures *,
! 				 const char *filename);
 static int symtable_load_symbols(struct compiling *);
 static struct symtable *symtable_init(void);
***************
*** 4251,4274 ****
 	if (ff == NULL)
 		return NULL;
! 
! 	st = symtable_init();
 	if (st == NULL) {
 		PyObject_FREE((void *)ff);
 		return NULL;
 	}
- 	st->st_future = ff;
- 	symtable_enter_scope(st, TOP, TYPE(n), n->n_lineno);
- 	if (st->st_errors > 0)
- 		goto fail;
- 	symtable_node(st, n);
- 	if (st->st_errors > 0)
- 		goto fail;
- 	
 	return st;
- fail:
- 	PyObject_FREE((void *)ff);
- 	st->st_future = NULL;
- 	PySymtable_Free(st);
- 	return NULL;
 }
 
--- 4252,4261 ----
 	if (ff == NULL)
 		return NULL;
! 	st = symtable_build(n, ff, filename);
 	if (st == NULL) {
 		PyObject_FREE((void *)ff);
 		return NULL;
 	}
 	return st;
 }
 
***************
*** 4320,4327 ****
 			flags->cf_flags = merged;
 		}
! 		if (symtable_build(&sc, n) < 0) {
 			com_free(&sc);
 			return NULL;
 		}
 	}
 	co = NULL;
--- 4307,4318 ----
 			flags->cf_flags = merged;
 		}
! 		sc.c_symtable = symtable_build(n, sc.c_future, sc.c_filename);
! 		if (sc.c_symtable == NULL) {
 			com_free(&sc);
 			return NULL;
 		}
+ 		/* reset symbol table for second pass */
+ 		sc.c_symtable->st_nscopes = 1;
+ 		sc.c_symtable->st_pass = 2;
 	}
 	co = NULL;
***************
*** 4444,4447 ****
--- 4435,4447 ----
 issue_warning(const char *msg, const char *filename, int lineno)
 {
+ 	if (PyErr_Occurred()) {
+ 		/* This can happen because symtable_node continues
+ 		 processing even after raising a SyntaxError.
+ 		 Calling PyErr_WarnExplicit now would clobber the
+ 		 pending exception; instead we fail and let that
+ 		 exception propagate.
+ 		*/
+ 		return -1;
+ 	}
 	if (PyErr_WarnExplicit(PyExc_SyntaxWarning, msg, filename,
 			 lineno, NULL, NULL) < 0)	{
***************
*** 4467,4487 ****
 /* Helper function for setting lineno and filename */
 
! static int
! symtable_build(struct compiling *c, node *n)
 {
! 	if ((c->c_symtable = symtable_init()) == NULL)
! 		return -1;
! 	c->c_symtable->st_future = c->c_future;
! 	c->c_symtable->st_filename = c->c_filename;
! 	symtable_enter_scope(c->c_symtable, TOP, TYPE(n), n->n_lineno);
! 	if (c->c_symtable->st_errors > 0)
! 		return -1;
! 	symtable_node(c->c_symtable, n);
! 	if (c->c_symtable->st_errors > 0)
! 		return -1;
! 	/* reset for second pass */
! 	c->c_symtable->st_nscopes = 1;
! 	c->c_symtable->st_pass = 2;
! 	return 0;
 }
 
--- 4467,4501 ----
 /* Helper function for setting lineno and filename */
 
! static struct symtable *
! symtable_build(node *n, PyFutureFeatures *ff, const char *filename)
 {
! 	struct symtable *st;
! 
! 	st = symtable_init();
! 	if (st == NULL)
! 		return NULL;
! 	st->st_future = ff;
! 	st->st_filename = filename;
! 	symtable_enter_scope(st, TOP, TYPE(n), n->n_lineno);
! 	if (st->st_errors > 0)
! 		goto fail;
! 	symtable_node(st, n);
! 	if (st->st_errors > 0)
! 		goto fail;
! 	return st;
! fail:
! 	if (!PyErr_Occurred()) {
! 		/* This could happen because after a syntax error is
! 		 detected, the symbol-table-building continues for
! 		 a while, and PyErr_Clear() might erroneously be
! 		 called during that process. One such case has been
! 		 fixed, but there might be more (now or later).
! 		*/
! 		PyErr_SetString(PyExc_SystemError, "lost exception");
! 	}
! 	st->st_future = NULL;
! 	st->st_filename = NULL;
! 	PySymtable_Free(st);
! 	return NULL;
 }
 

AltStyle によって変換されたページ (->オリジナル) /