Disallow continue referring to a non-IterationStatement. Fix #287

Simplifies handling of labels (their definition/references can be easily
figured out at parse time, no need to do it in `figure_out_scope`).
This commit is contained in:
Mihai Bazon
2013-09-02 19:36:16 +03:00
parent 1c6efdae34
commit 85b527ba3d
4 changed files with 34 additions and 48 deletions

View File

@@ -828,6 +828,18 @@ function parse($TEXT, options) {
S.labels.push(label);
var stat = statement();
S.labels.pop();
if (!(stat instanceof AST_IterationStatement)) {
// check for `continue` that refers to this label.
// those should be reported as syntax errors.
// https://github.com/mishoo/UglifyJS2/issues/287
label.references.forEach(function(ref){
if (ref instanceof AST_Continue) {
ref = ref.label.start;
croak("Continue label `" + label.name + "` refers to non-loop statement.",
ref.line, ref.col, ref.pos);
}
});
}
return new AST_LabeledStatement({ body: stat, label: label });
};
@@ -836,18 +848,22 @@ function parse($TEXT, options) {
};
function break_cont(type) {
var label = null;
var label = null, ldef;
if (!can_insert_semicolon()) {
label = as_symbol(AST_LabelRef, true);
}
if (label != null) {
if (!find_if(function(l){ return l.name == label.name }, S.labels))
ldef = find_if(function(l){ return l.name == label.name }, S.labels);
if (!ldef)
croak("Undefined label " + label.name);
label.thedef = ldef;
}
else if (S.in_loop == 0)
croak(type.TYPE + " not inside a loop or switch");
semicolon();
return new type({ label: label });
var stat = new type({ label: label });
if (ldef) ldef.references.push(stat);
return stat;
};
function for_() {