mirror of
https://github.com/zeek/zeek.git
synced 2025-10-07 17:18:20 +00:00
Merge remote-tracking branch 'origin/topic/jsiwek/const'
* origin/topic/jsiwek/const: Make const variables actually constant. Addresses #922. Closes #922.
This commit is contained in:
commit
ea6b62f586
11 changed files with 128 additions and 11 deletions
7
CHANGES
7
CHANGES
|
@ -1,4 +1,11 @@
|
|||
|
||||
2.1-231 | 2012-12-14 14:51:35 -0800
|
||||
|
||||
* Make const variables actually constant. Both local and global
|
||||
variables declared with "const" could be modified, but now
|
||||
expressions that would modify them generate an error message at
|
||||
parse-time. Addresses #922. (Jon Siwek)
|
||||
|
||||
2.1-229 | 2012-12-14 14:46:12 -0800
|
||||
|
||||
* Fix memory leak in ASCII reader when encoutering errors in input.
|
||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
|||
2.1-229
|
||||
2.1-231
|
||||
|
|
|
@ -21,12 +21,10 @@ redef Cluster::manager2worker_events += /Notice::begin_suppression/;
|
|||
redef Cluster::worker2manager_events += /Notice::cluster_notice/;
|
||||
|
||||
@if ( Cluster::local_node_type() != Cluster::MANAGER )
|
||||
|
||||
# The notice policy is completely handled by the manager and shouldn't be
|
||||
# done by workers or proxies to save time for packet processing.
|
||||
event bro_init() &priority=11
|
||||
{
|
||||
Notice::policy = table();
|
||||
}
|
||||
redef Notice::policy = table();
|
||||
|
||||
event Notice::begin_suppression(n: Notice::Info)
|
||||
{
|
||||
|
|
15
src/Expr.cc
15
src/Expr.cc
|
@ -229,9 +229,10 @@ bool Expr::DoUnserialize(UnserialInfo* info)
|
|||
}
|
||||
|
||||
|
||||
NameExpr::NameExpr(ID* arg_id) : Expr(EXPR_NAME)
|
||||
NameExpr::NameExpr(ID* arg_id, bool const_init) : Expr(EXPR_NAME)
|
||||
{
|
||||
id = arg_id;
|
||||
in_const_init = const_init;
|
||||
SetType(id->Type()->Ref());
|
||||
|
||||
EventHandler* h = event_registry->Lookup(id->Name());
|
||||
|
@ -287,6 +288,9 @@ Expr* NameExpr::MakeLvalue()
|
|||
if ( id->AsType() )
|
||||
ExprError("Type name is not an lvalue");
|
||||
|
||||
if ( id->IsConst() && ! in_const_init )
|
||||
ExprError("const is not a modifiable lvalue");
|
||||
|
||||
return new RefExpr(this);
|
||||
}
|
||||
|
||||
|
@ -337,9 +341,11 @@ bool NameExpr::DoSerialize(SerialInfo* info) const
|
|||
|
||||
// Write out just the name of the function if requested.
|
||||
if ( info->globals_as_names && id->IsGlobal() )
|
||||
return SERIALIZE('n') && SERIALIZE(id->Name());
|
||||
return SERIALIZE('n') && SERIALIZE(id->Name()) &&
|
||||
SERIALIZE(in_const_init);
|
||||
else
|
||||
return SERIALIZE('f') && id->Serialize(info);
|
||||
return SERIALIZE('f') && id->Serialize(info) &&
|
||||
SERIALIZE(in_const_init);
|
||||
}
|
||||
|
||||
bool NameExpr::DoUnserialize(UnserialInfo* info)
|
||||
|
@ -370,6 +376,9 @@ bool NameExpr::DoUnserialize(UnserialInfo* info)
|
|||
if ( ! id )
|
||||
return false;
|
||||
|
||||
if ( ! UNSERIALIZE(&in_const_init) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -198,7 +198,7 @@ protected:
|
|||
|
||||
class NameExpr : public Expr {
|
||||
public:
|
||||
NameExpr(ID* id);
|
||||
NameExpr(ID* id, bool const_init = false);
|
||||
~NameExpr();
|
||||
|
||||
ID* Id() const { return id; }
|
||||
|
@ -220,6 +220,7 @@ protected:
|
|||
DECLARE_SERIAL(NameExpr);
|
||||
|
||||
ID* id;
|
||||
bool in_const_init;
|
||||
};
|
||||
|
||||
class ConstExpr : public Expr {
|
||||
|
|
|
@ -210,7 +210,6 @@ static void make_var(ID* id, BroType* t, init_class c, Expr* init,
|
|||
// defined.
|
||||
Func* f = new BroFunc(id, 0, 0, 0, 0);
|
||||
id->SetVal(new Val(f));
|
||||
id->SetConst();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -233,8 +232,9 @@ Stmt* add_local(ID* id, BroType* t, init_class c, Expr* init,
|
|||
|
||||
Ref(id);
|
||||
|
||||
Expr* name_expr = new NameExpr(id, dt == VAR_CONST);
|
||||
Stmt* stmt =
|
||||
new ExprStmt(new AssignExpr(new NameExpr(id), init, 0, 0,
|
||||
new ExprStmt(new AssignExpr(name_expr, init, 0, 0,
|
||||
id->Attrs() ? id->Attrs()->Attrs() : 0 ));
|
||||
stmt->SetLocationInfo(init->GetLocationInfo());
|
||||
|
||||
|
|
13
testing/btest/Baseline/language.const/invalid.stderr
Normal file
13
testing/btest/Baseline/language.const/invalid.stderr
Normal file
|
@ -0,0 +1,13 @@
|
|||
error in ./invalid.bro, line 15: const is not a modifiable lvalue (foo)
|
||||
error in ./invalid.bro, line 16: const is not a modifiable lvalue (foo)
|
||||
error in ./invalid.bro, line 17: const is not a modifiable lvalue (bar)
|
||||
error in ./invalid.bro, line 17: const is not a modifiable lvalue (foo)
|
||||
error in ./invalid.bro, line 18: const is not a modifiable lvalue (foo)
|
||||
error in ./invalid.bro, line 19: const is not a modifiable lvalue (foo)
|
||||
error in ./invalid.bro, line 20: const is not a modifiable lvalue (foo)
|
||||
error in ./invalid.bro, line 22: const is not a modifiable lvalue (foo)
|
||||
error in ./invalid.bro, line 25: const is not a modifiable lvalue (bar)
|
||||
error in ./invalid.bro, line 26: const is not a modifiable lvalue (baz)
|
||||
error in ./invalid.bro, line 27: const is not a modifiable lvalue (bar)
|
||||
error in ./invalid.bro, line 28: const is not a modifiable lvalue (baz)
|
||||
error in ./invalid.bro, line 33: const is not a modifiable lvalue (foo)
|
0
testing/btest/Baseline/language.const/invalid.stdout
Normal file
0
testing/btest/Baseline/language.const/invalid.stdout
Normal file
0
testing/btest/Baseline/language.const/valid.stderr
Normal file
0
testing/btest/Baseline/language.const/valid.stderr
Normal file
10
testing/btest/Baseline/language.const/valid.stdout
Normal file
10
testing/btest/Baseline/language.const/valid.stdout
Normal file
|
@ -0,0 +1,10 @@
|
|||
40
|
||||
enter f, 10
|
||||
exit f, 110
|
||||
enter f, 9
|
||||
exit f, 109
|
||||
enter f, 7
|
||||
exit f, 107
|
||||
foo, 10
|
||||
bar, 9
|
||||
baz, 7
|
79
testing/btest/language/const.bro
Normal file
79
testing/btest/language/const.bro
Normal file
|
@ -0,0 +1,79 @@
|
|||
# @TEST-EXEC: bro -b valid.bro 2>valid.stderr 1>valid.stdout
|
||||
# @TEST-EXEC: btest-diff valid.stderr
|
||||
# @TEST-EXEC: btest-diff valid.stdout
|
||||
|
||||
# @TEST-EXEC-FAIL: bro -b invalid.bro 2>invalid.stderr 1>invalid.stdout
|
||||
# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff invalid.stderr
|
||||
# @TEST-EXEC: btest-diff invalid.stdout
|
||||
|
||||
@TEST-START-FILE valid.bro
|
||||
# First some simple code that should be valid and error-free.
|
||||
|
||||
function f(c: count)
|
||||
{
|
||||
print "enter f", c;
|
||||
c = c + 100;
|
||||
print "exit f", c;
|
||||
}
|
||||
|
||||
const foo = 0 &redef;
|
||||
redef foo = 10;
|
||||
|
||||
const bar = 9;
|
||||
|
||||
event bro_init()
|
||||
{
|
||||
const baz = 7;
|
||||
local i = foo;
|
||||
i = i + bar + 2;
|
||||
i = i + baz + 11;
|
||||
++i;
|
||||
print i;
|
||||
--i;
|
||||
f(foo);
|
||||
f(bar);
|
||||
f(baz);
|
||||
print "foo", foo;
|
||||
print "bar", bar;
|
||||
print "baz", baz;
|
||||
}
|
||||
|
||||
@TEST-END-FILE
|
||||
|
||||
@TEST-START-FILE invalid.bro
|
||||
# Now some const assignments that should generate errors at parse-time.
|
||||
|
||||
const foo = 0 &redef;
|
||||
redef foo = 10;
|
||||
|
||||
const bar = 9;
|
||||
|
||||
event bro_init()
|
||||
{
|
||||
const baz = 7;
|
||||
local s = 0;
|
||||
|
||||
print "nope";
|
||||
|
||||
foo = 100;
|
||||
foo = bar;
|
||||
foo = bar = baz;
|
||||
foo = s;
|
||||
++foo;
|
||||
s = foo = bar;
|
||||
|
||||
if ( foo = 0 )
|
||||
print "nope";
|
||||
|
||||
bar = 1 + 1;
|
||||
baz = s;
|
||||
++bar;
|
||||
--baz;
|
||||
|
||||
print "foo", foo;
|
||||
print "bar", bar;
|
||||
print "baz", baz;
|
||||
print "foo=foo", foo = foo;
|
||||
}
|
||||
|
||||
@TEST-END-FILE
|
Loading…
Add table
Add a link
Reference in a new issue