Detect functions that try to bind variables from an outer scope.

And raise an error saying that's not supported.
Addresses BIT-1233.
This commit is contained in:
Jon Siwek 2014-08-22 16:49:10 -05:00
parent f8895843cf
commit 3521a92a00
4 changed files with 76 additions and 2 deletions

View file

@ -660,8 +660,13 @@ void Case::Describe(ODesc* d) const
TraversalCode Case::Traverse(TraversalCallback* cb) const
{
TraversalCode tc = cases->Traverse(cb);
TraversalCode tc;
if ( cases )
{
tc = cases->Traverse(cb);
HANDLE_TC_STMT_PRE(tc);
}
tc = s->Traverse(cb);
HANDLE_TC_STMT_PRE(tc);

View file

@ -9,6 +9,7 @@
#include "Serializer.h"
#include "RemoteSerializer.h"
#include "EventRegistry.h"
#include "Traverse.h"
static Val* init_val(Expr* init, const BroType* t, Val* aggr)
{
@ -392,6 +393,34 @@ void begin_func(ID* id, const char* module_name, function_flavor flavor,
}
}
class OuterParamBindingFinder : public TraversalCallback {
public:
OuterParamBindingFinder(Scope* s)
: scope(s) { }
virtual TraversalCode PreExpr(const Expr*);
Scope* scope;
vector<const NameExpr*> outer_param_references;
};
TraversalCode OuterParamBindingFinder::PreExpr(const Expr* expr)
{
if ( expr->Tag() != EXPR_NAME )
return TC_CONTINUE;
const NameExpr* e = static_cast<const NameExpr*>(expr);
if ( e->Id()->IsGlobal() )
return TC_CONTINUE;
if ( scope->GetIDs()->Lookup(e->Id()->Name()) )
return TC_CONTINUE;
outer_param_references.push_back(e);
return TC_CONTINUE;
}
void end_func(Stmt* body, attr_list* attrs)
{
int frame_size = current_scope()->Length();
@ -429,6 +458,16 @@ void end_func(Stmt* body, attr_list* attrs)
}
}
if ( streq(id->Name(), "anonymous-function") )
{
OuterParamBindingFinder cb(scope);
body->Traverse(&cb);
for ( size_t i = 0; i < cb.outer_param_references.size(); ++i )
cb.outer_param_references[i]->Error(
"referencing outer function parameters not supported");
}
if ( id->HasVal() )
id->ID_Val()->AsFunc()->AddBody(body, inits, frame_size, priority);
else

View file

@ -0,0 +1,3 @@
error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.outer_param_binding/outer_param_binding.bro, line 16: referencing outer function parameters not supported (c)
error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.outer_param_binding/outer_param_binding.bro, line 16: referencing outer function parameters not supported (d)
error in /Users/jsiwek/Projects/bro/bro/testing/btest/.tmp/language.outer_param_binding/outer_param_binding.bro, line 17: referencing outer function parameters not supported (b)

View file

@ -0,0 +1,27 @@
# @TEST-EXEC-FAIL: bro -b %INPUT >out 2>&1
# @TEST-EXEC: TEST_DIFF_CANONIFIER=$SCRIPTS/diff-remove-abspath btest-diff out
type Foo: record {
x: function(a: string) : string;
};
function bar(b: string, c: string)
{
local f: Foo;
local d = 8;
f = [$x=function(a: string) : string
{
local x = 0;
print x;
print c, d;
return cat(a, " ", b);
}
];
print f$x("2");
}
event bro_init()
{
bar("1", "20");
}