Commit 4fccd71f authored by Marius Wachtler's avatar Marius Wachtler

Merge commit '641bb659' into refcounting

parents 5d803aff 641bb659
......@@ -14,6 +14,8 @@
#include "codegen/cpython_ast.h"
#include <set>
#include "llvm/ADT/STLExtras.h"
#include "core/types.h"
......@@ -93,16 +95,51 @@ public:
return pool->get(static_cast<BoxedString*>(ident)->s());
}
AST_arguments* convert(arguments_ty ident) {
AST_arguments* convert(arguments_ty ident, AST* parent) {
auto r = new AST_arguments();
convertAll<expr_ty>(ident->args, r->args);
convertAll<expr_ty>(ident->defaults, r->defaults);
r->vararg = convert(ident->vararg);
r->kwarg = convert(ident->kwarg);
if ((!r->vararg.s().empty()) && (!r->kwarg.s().empty()) && (r->vararg == r->kwarg)) {
char buf[1024];
snprintf(buf, sizeof(buf), "duplicate argument '%s' in function definition", r->vararg.c_str());
raiseSyntaxError(buf, parent->lineno, parent->col_offset, fn, "", true);
}
std::set<InternedString> seen;
if (!r->vararg.s().empty()) {
seen.insert(r->vararg);
}
if (!r->kwarg.s().empty()) {
seen.insert(r->kwarg);
}
checkDuplicateArgs(parent, r->args, &seen);
return r;
}
void checkDuplicateArgs(AST* parent, std::vector<AST_expr*> args, std::set<InternedString>* seen) {
for (auto arg : args) {
if (arg->type == AST_TYPE::Name) {
auto name_node = static_cast<AST_Name*>(arg);
if (seen->find(name_node->id) != seen->end()) {
char buf[1024];
snprintf(buf, sizeof(buf), "duplicate argument '%s' in function definition", name_node->id.c_str());
raiseSyntaxError(buf, parent->lineno, parent->col_offset, fn, "", true);
}
seen->insert(name_node->id);
} else if (arg->type == AST_TYPE::Tuple) {
auto slice_node = static_cast<AST_Tuple*>(arg);
checkDuplicateArgs(parent, slice_node->elts, seen);
} else {
RELEASE_ASSERT(0, "");
}
}
}
#define CASE(N) \
case N: \
return AST_TYPE::N
......@@ -244,8 +281,10 @@ public:
}
case Lambda_kind: {
auto r = new AST_Lambda();
r->lineno = expr->lineno;
r->col_offset = expr->col_offset;
auto v = expr->v.Lambda;
r->args = convert(v.args);
r->args = convert(v.args, r);
r->body = convert(v.body);
return r;
}
......@@ -467,9 +506,11 @@ public:
switch (stmt->kind) {
case FunctionDef_kind: {
auto r = new AST_FunctionDef();
r->lineno = stmt->lineno;
r->col_offset = stmt->col_offset;
auto v = stmt->v.FunctionDef;
r->name = convert(v.name);
r->args = convert(v.args);
r->args = convert(v.args, r);
r->body = convert<stmt_ty, AST_stmt*>(v.body);
r->decorator_list = convert<expr_ty, AST_expr*>(v.decorator_list);
return r;
......
......@@ -36,3 +36,34 @@ try:
assert False
except SyntaxError:
pass
# test duplicate args
try:
exec compile('lambda x, x: none', 'foo', 'exec')
except SyntaxError as e:
print(e)
else:
raise Exception('SyntaxError not raised')
# test nests duplicate args
try:
exec compile('lambda a, (b, (c, a)): none', 'foo', 'exec')
except SyntaxError as e:
print(e)
else:
raise Exception('SyntaxError not raised')
# test duplicate vararg and kwarg
try:
eval('lambda *a, **a: 0')
except SyntaxError as e:
print(e)
else:
raise Exception('SyntaxError not raised')
try:
eval('lambda a, *a: 0')
except SyntaxError as e:
print(e)
else:
raise Exception('SyntaxError not raised')
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