Commit fd3ff03d authored by adamk's avatar adamk Committed by Commit bot

Fix harmony sloppy block scoping dynamic redeclaration check

The previous code did not properly check for harmony const when
doing the dynamic redeclaration check. This was masked in the
test because each eval had an initializer, and the initializer was what
triggered the exception.

This patch tightens the test by removing initializers and fixes the bug in
DeclareLookupSlot.

Also change the test to use assertThrows where possible.

BUG=v8:4550
LOG=n

Review URL: https://codereview.chromium.org/1437003006

Cr-Commit-Position: refs/heads/master@{#31995}
parent cf2f6b80
......@@ -231,7 +231,8 @@ Object* DeclareLookupSlot(Isolate* isolate, Handle<String> name,
&binding_flags);
if (attributes != ABSENT &&
(binding_flags == MUTABLE_CHECK_INITIALIZED ||
binding_flags == IMMUTABLE_CHECK_INITIALIZED)) {
binding_flags == IMMUTABLE_CHECK_INITIALIZED ||
binding_flags == IMMUTABLE_CHECK_INITIALIZED_HARMONY)) {
return ThrowRedeclarationError(isolate, name);
}
attr = static_cast<PropertyAttributes>(attr & ~EVAL_DECLARED);
......
......@@ -6,61 +6,36 @@
// Var-let conflict in a function throws, even if the var is in an eval
let caught = false;
// Throws at the top level of a function
try {
(function() {
let x = 1;
eval('const x = 2');
})()
} catch (e) {
caught = true;
}
assertTrue(caught);
assertThrows(function() {
let x = 1;
eval('const x = 2');
}, TypeError);
// If the eval is in its own block scope, throws
caught = false;
try {
(function() {
let y = 1;
{ eval('const y = 2'); }
})()
} catch (e) {
caught = true;
}
assertTrue(caught);
assertThrows(function() {
let y = 1;
{ eval('const y = 2'); }
}, TypeError);
// If the let is in its own block scope, with the eval, throws
caught = false
try {
(function() {
{
let x = 1;
eval('const x = 2');
}
})();
} catch (e) {
caught = true;
}
assertTrue(caught);
assertThrows(function() {
{
let x = 1;
eval('const x = 2');
}
}, TypeError);
// Legal if the let is no longer visible
caught = false
try {
(function() {
{
let x = 1;
}
eval('const x = 2');
})();
} catch (e) {
caught = true;
}
assertFalse(caught);
assertDoesNotThrow(function() {
{
let x = 1;
}
eval('const x = 2');
});
// In global scope
caught = false;
let caught = false;
try {
let z = 1;
eval('const z = 2');
......
......@@ -6,116 +6,68 @@
// Var-let conflict in a function throws, even if the var is in an eval
let caught = false;
// Throws at the top level of a function
try {
(function() {
let x = 1;
eval('var x = 2');
})()
} catch (e) {
caught = true;
}
assertTrue(caught);
assertThrows(function() {
let x = 1;
eval('var x');
}, TypeError);
// If the eval is in its own block scope, throws
caught = false;
try {
(function() {
let y = 1;
{ eval('var y = 2'); }
})()
} catch (e) {
caught = true;
}
assertTrue(caught);
assertThrows(function() {
let y = 1;
{ eval('var y'); }
}, TypeError);
// If the let is in its own block scope, with the eval, throws
caught = false
try {
(function() {
{
let x = 1;
eval('var x = 2');
}
})();
} catch (e) {
caught = true;
}
assertTrue(caught);
assertThrows(function() {
{
let x = 1;
eval('var x');
}
}, TypeError);
// Legal if the let is no longer visible
caught = false
try {
(function() {
{
let x = 1;
}
eval('var x = 2');
})();
} catch (e) {
caught = true;
}
assertFalse(caught);
assertDoesNotThrow(function() {
{
let x = 1;
}
eval('var x');
});
// All the same works for const:
// Throws at the top level of a function
try {
(function() {
const x = 1;
eval('var x = 2');
})();
} catch (e) {
caught = true;
}
assertTrue(caught);
assertThrows(function() {
const x = 1;
eval('var x');
}, TypeError);
// If the eval is in its own block scope, throws
caught = false;
try {
(function() {
const y = 1;
{ eval('var y = 2'); }
})();
} catch (e) {
caught = true;
}
assertTrue(caught);
assertThrows(function() {
const y = 1;
{ eval('var y'); }
}, TypeError);
// If the const is in its own block scope, with the eval, throws
caught = false
try {
(function() {
{
const x = 1;
eval('var x = 2');
}
})();
} catch (e) {
caught = true;
}
assertTrue(caught);
assertThrows(function() {
{
const x = 1;
eval('var x');
}
}, TypeError);
// Legal if the const is no longer visible
caught = false
try {
(function() {
{
const x = 1;
}
eval('var x = 2');
})();
} catch (e) {
caught = true;
}
assertFalse(caught);
assertDoesNotThrow(function() {
{
const x = 1;
}
eval('var x');
});
// In global scope
caught = false;
let caught = false;
try {
let z = 1;
eval('var z = 2');
eval('var z');
} catch (e) {
caught = true;
}
......@@ -138,7 +90,7 @@ caught = false;
try {
(function() {
with ({x: 1}) {
eval("var x = 2;");
eval("var x");
}
})();
} catch (e) {
......@@ -152,7 +104,7 @@ try {
(function() {
let x;
with ({x: 1}) {
eval("var x = 2;");
eval("var x");
}
})();
} catch (e) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment