Move all new's to global_arena, and remove ASAN disabling (#690)

Note this changes identifiers from char* to string to avoid malloc.

Fixes #580
This commit is contained in:
Jon Meow
2021-08-02 11:08:22 -07:00
committed by GitHub
parent f1028fcc27
commit 9829f188b7
18 changed files with 130 additions and 120 deletions
-8
View File
@@ -26,10 +26,6 @@ cc_binary(
":executable_semantics",
"testdata/%s.carbon" % e,
],
env = {
# TODO(#580): Remove this when leaks are fixed.
"ASAN_OPTIONS": "detect_leaks=0",
},
golden = "testdata/%s.golden" % e,
) for e in TEST_LIST]
@@ -49,10 +45,6 @@ test_suite(
":executable_semantics",
"testdata/%s.carbon" % e,
],
env = {
# TODO(#580): Remove this when leaks are fixed.
"ASAN_OPTIONS": "detect_leaks=0",
},
golden = "testdata/%s.golden" % e,
golden_is_subset = True,
) for e in TEST_LIST]
+2 -8
View File
@@ -42,10 +42,6 @@ cc_library(
cc_test(
name = "expression_test",
srcs = ["expression_test.cpp"],
env = {
# TODO(#580): Remove this when leaks are fixed.
"ASAN_OPTIONS": "detect_leaks=0",
},
deps = [
":expression",
"//executable_semantics/syntax:paren_contents",
@@ -82,6 +78,7 @@ cc_library(
deps = [
":expression",
"//common:ostream",
"//executable_semantics/common:arena",
"//executable_semantics/common:error",
"@llvm-project//llvm:Support",
],
@@ -90,10 +87,6 @@ cc_library(
cc_test(
name = "pattern_test",
srcs = ["pattern_test.cpp"],
env = {
# TODO(#580): Remove this when leaks are fixed.
"ASAN_OPTIONS": "detect_leaks=0",
},
deps = [
":pattern",
"//executable_semantics/syntax:paren_contents",
@@ -112,6 +105,7 @@ cc_library(
":pattern",
"//common:check",
"//common:ostream",
"//executable_semantics/common:arena",
"@llvm-project//llvm:Support",
],
)
+3 -1
View File
@@ -4,11 +4,13 @@
#include "executable_semantics/ast/member.h"
#include "executable_semantics/common/arena.h"
namespace Carbon {
auto Member::MakeFieldMember(int line_num, const BindingPattern* binding)
-> Member* {
auto m = new Member();
auto m = global_arena->New<Member>();
m->line_num = line_num;
m->value = FieldMember({.binding = binding});
return m;
+6 -3
View File
@@ -8,6 +8,7 @@
#include "common/ostream.h"
#include "executable_semantics/ast/expression.h"
#include "executable_semantics/common/arena.h"
#include "executable_semantics/common/error.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Casting.h"
@@ -57,7 +58,8 @@ TuplePattern::TuplePattern(const Expression* tuple_literal)
: Pattern(Kind::TuplePattern, tuple_literal->line_num) {
const auto& tuple = tuple_literal->GetTupleLiteral();
for (const FieldInitializer& init : tuple.fields) {
fields.push_back(Field(init.name, new ExpressionPattern(init.expression)));
fields.push_back(Field(
init.name, global_arena->New<ExpressionPattern>(init.expression)));
}
}
@@ -75,7 +77,7 @@ auto PatternFromParenContents(int line_num,
auto TuplePatternFromParenContents(int line_num,
const ParenContents<Pattern>& paren_contents)
-> const TuplePattern* {
return new TuplePattern(
return global_arena->New<TuplePattern>(
line_num, paren_contents.TupleElements<TuplePattern::Field>(line_num));
}
@@ -98,7 +100,8 @@ auto ParenExpressionToParenPattern(const ParenContents<Expression>& contents)
.elements = {}, .has_trailing_comma = contents.has_trailing_comma};
for (const auto& element : contents.elements) {
result.elements.push_back(
{.name = element.name, .term = new ExpressionPattern(element.term)});
{.name = element.name,
.term = global_arena->New<ExpressionPattern>(element.term)});
}
return result;
}
+9 -8
View File
@@ -5,6 +5,7 @@
#include "executable_semantics/ast/pattern.h"
#include "executable_semantics/ast/expression.h"
#include "executable_semantics/common/arena.h"
#include "executable_semantics/syntax/paren_contents.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@@ -51,7 +52,7 @@ TEST(PatternTest, UnaryNoCommaAsPattern) {
// ```
ParenContents<Pattern> contents = {
.elements = {{.name = std::nullopt,
.term = new AutoPattern(/*line_num=*/2)}},
.term = global_arena->New<AutoPattern>(/*line_num=*/2)}},
.has_trailing_comma = false};
const Pattern* pattern = PatternFromParenContents(/*line_num=*/1, contents);
@@ -62,7 +63,7 @@ TEST(PatternTest, UnaryNoCommaAsPattern) {
TEST(PatternTest, UnaryNoCommaAsTuplePattern) {
ParenContents<Pattern> contents = {
.elements = {{.name = std::nullopt,
.term = new AutoPattern(/*line_num=*/2)}},
.term = global_arena->New<AutoPattern>(/*line_num=*/2)}},
.has_trailing_comma = false};
const TuplePattern* tuple =
@@ -74,7 +75,7 @@ TEST(PatternTest, UnaryNoCommaAsTuplePattern) {
TEST(PatternTest, UnaryWithCommaAsPattern) {
ParenContents<Pattern> contents = {
.elements = {{.name = std::nullopt,
.term = new AutoPattern(/*line_num=*/2)}},
.term = global_arena->New<AutoPattern>(/*line_num=*/2)}},
.has_trailing_comma = true};
const Pattern* pattern = PatternFromParenContents(/*line_num=*/1, contents);
@@ -87,7 +88,7 @@ TEST(PatternTest, UnaryWithCommaAsPattern) {
TEST(PatternTest, UnaryWithCommaAsTuplePattern) {
ParenContents<Pattern> contents = {
.elements = {{.name = std::nullopt,
.term = new AutoPattern(/*line_num=*/2)}},
.term = global_arena->New<AutoPattern>(/*line_num=*/2)}},
.has_trailing_comma = true};
const TuplePattern* tuple =
@@ -99,9 +100,9 @@ TEST(PatternTest, UnaryWithCommaAsTuplePattern) {
TEST(PatternTest, BinaryAsPattern) {
ParenContents<Pattern> contents = {
.elements = {{.name = std::nullopt,
.term = new AutoPattern(/*line_num=*/2)},
.term = global_arena->New<AutoPattern>(/*line_num=*/2)},
{.name = std::nullopt,
.term = new AutoPattern(/*line_num=*/3)}},
.term = global_arena->New<AutoPattern>(/*line_num=*/3)}},
.has_trailing_comma = true};
const Pattern* pattern = PatternFromParenContents(/*line_num=*/1, contents);
@@ -114,9 +115,9 @@ TEST(PatternTest, BinaryAsPattern) {
TEST(PatternTest, BinaryAsTuplePattern) {
ParenContents<Pattern> contents = {
.elements = {{.name = std::nullopt,
.term = new AutoPattern(/*line_num=*/2)},
.term = global_arena->New<AutoPattern>(/*line_num=*/2)},
{.name = std::nullopt,
.term = new AutoPattern(/*line_num=*/3)}},
.term = global_arena->New<AutoPattern>(/*line_num=*/3)}},
.has_trailing_comma = true};
const TuplePattern* tuple =
+15 -14
View File
@@ -5,6 +5,7 @@
#include "executable_semantics/ast/statement.h"
#include "common/check.h"
#include "executable_semantics/common/arena.h"
namespace Carbon {
@@ -62,7 +63,7 @@ auto Statement::GetAwait() const -> const Await& {
auto Statement::MakeExpressionStatement(int line_num, const Expression* exp)
-> const Statement* {
auto* s = new Statement();
auto* s = global_arena->New<Statement>();
s->line_num = line_num;
s->value = ExpressionStatement({.exp = exp});
return s;
@@ -70,7 +71,7 @@ auto Statement::MakeExpressionStatement(int line_num, const Expression* exp)
auto Statement::MakeAssign(int line_num, const Expression* lhs,
const Expression* rhs) -> const Statement* {
auto* s = new Statement();
auto* s = global_arena->New<Statement>();
s->line_num = line_num;
s->value = Assign({.lhs = lhs, .rhs = rhs});
return s;
@@ -79,7 +80,7 @@ auto Statement::MakeAssign(int line_num, const Expression* lhs,
auto Statement::MakeVariableDefinition(int line_num, const Pattern* pat,
const Expression* init)
-> const Statement* {
auto* s = new Statement();
auto* s = global_arena->New<Statement>();
s->line_num = line_num;
s->value = VariableDefinition({.pat = pat, .init = init});
return s;
@@ -88,7 +89,7 @@ auto Statement::MakeVariableDefinition(int line_num, const Pattern* pat,
auto Statement::MakeIf(int line_num, const Expression* cond,
const Statement* then_stmt, const Statement* else_stmt)
-> const Statement* {
auto* s = new Statement();
auto* s = global_arena->New<Statement>();
s->line_num = line_num;
s->value = If({.cond = cond, .then_stmt = then_stmt, .else_stmt = else_stmt});
return s;
@@ -96,21 +97,21 @@ auto Statement::MakeIf(int line_num, const Expression* cond,
auto Statement::MakeWhile(int line_num, const Expression* cond,
const Statement* body) -> const Statement* {
auto* s = new Statement();
auto* s = global_arena->New<Statement>();
s->line_num = line_num;
s->value = While({.cond = cond, .body = body});
return s;
}
auto Statement::MakeBreak(int line_num) -> const Statement* {
auto* s = new Statement();
auto* s = global_arena->New<Statement>();
s->line_num = line_num;
s->value = Break();
return s;
}
auto Statement::MakeContinue(int line_num) -> const Statement* {
auto* s = new Statement();
auto* s = global_arena->New<Statement>();
s->line_num = line_num;
s->value = Continue();
return s;
@@ -118,7 +119,7 @@ auto Statement::MakeContinue(int line_num) -> const Statement* {
auto Statement::MakeReturn(int line_num, const Expression* e)
-> const Statement* {
auto* s = new Statement();
auto* s = global_arena->New<Statement>();
s->line_num = line_num;
s->value = Return({.exp = e});
return s;
@@ -126,7 +127,7 @@ auto Statement::MakeReturn(int line_num, const Expression* e)
auto Statement::MakeSequence(int line_num, const Statement* s1,
const Statement* s2) -> const Statement* {
auto* s = new Statement();
auto* s = global_arena->New<Statement>();
s->line_num = line_num;
s->value = Sequence({.stmt = s1, .next = s2});
return s;
@@ -134,7 +135,7 @@ auto Statement::MakeSequence(int line_num, const Statement* s1,
auto Statement::MakeBlock(int line_num, const Statement* stmt)
-> const Statement* {
auto* s = new Statement();
auto* s = global_arena->New<Statement>();
s->line_num = line_num;
s->value = Block({.stmt = stmt});
return s;
@@ -144,7 +145,7 @@ auto Statement::MakeMatch(
int line_num, const Expression* exp,
std::list<std::pair<const Pattern*, const Statement*>>* clauses)
-> const Statement* {
auto* s = new Statement();
auto* s = global_arena->New<Statement>();
s->line_num = line_num;
s->value = Match({.exp = exp, .clauses = clauses});
return s;
@@ -155,7 +156,7 @@ auto Statement::MakeMatch(
auto Statement::MakeContinuation(int line_num,
std::string continuation_variable,
const Statement* body) -> const Statement* {
auto* s = new Statement();
auto* s = global_arena->New<Statement>();
s->line_num = line_num;
s->value =
Continuation({.continuation_variable = std::move(continuation_variable),
@@ -166,7 +167,7 @@ auto Statement::MakeContinuation(int line_num,
// Returns an AST node for a run statement give its line number and argument.
auto Statement::MakeRun(int line_num, const Expression* argument)
-> const Statement* {
auto* s = new Statement();
auto* s = global_arena->New<Statement>();
s->line_num = line_num;
s->value = Run({.argument = argument});
return s;
@@ -174,7 +175,7 @@ auto Statement::MakeRun(int line_num, const Expression* argument)
// Returns an AST node for an await statement give its line number.
auto Statement::MakeAwait(int line_num) -> const Statement* {
auto* s = new Statement();
auto* s = global_arena->New<Statement>();
s->line_num = line_num;
s->value = Await();
return s;
+1 -1
View File
@@ -37,7 +37,7 @@ class Arena {
class ArenaEntryTyped : public ArenaEntry {
public:
template <typename... Args>
explicit ArenaEntryTyped(Args&... args)
explicit ArenaEntryTyped(Args&&... args)
: instance(std::forward<Args>(args)...) {}
auto Instance() -> T* { return &instance; }
+5
View File
@@ -17,6 +17,7 @@ cc_library(
"//executable_semantics/ast:expression",
"//executable_semantics/ast:function_definition",
"//executable_semantics/ast:statement",
"//executable_semantics/common:arena",
"@llvm-project//llvm:Support",
],
)
@@ -97,6 +98,7 @@ cc_library(
"//executable_semantics/ast:declaration",
"//executable_semantics/ast:expression",
"//executable_semantics/ast:function_definition",
"//executable_semantics/common:arena",
"//executable_semantics/common:tracing_flag",
"@llvm-project//llvm:Support",
],
@@ -113,6 +115,7 @@ cc_library(
"//executable_semantics/ast:expression",
"//executable_semantics/ast:function_definition",
"//executable_semantics/ast:statement",
"//executable_semantics/common:arena",
"//executable_semantics/common:tracing_flag",
"@llvm-project//llvm:Support",
],
@@ -129,6 +132,8 @@ cc_library(
"//common:ostream",
"//executable_semantics/ast:function_definition",
"//executable_semantics/ast:statement",
"//executable_semantics/common:arena",
"//executable_semantics/common:error",
"@llvm-project//llvm:Support",
],
)
+6 -5
View File
@@ -12,37 +12,38 @@
#include "executable_semantics/ast/expression.h"
#include "executable_semantics/ast/function_definition.h"
#include "executable_semantics/common/arena.h"
#include "executable_semantics/interpreter/stack.h"
#include "llvm/ADT/StringExtras.h"
namespace Carbon {
auto Action::MakeLValAction(const Expression* e) -> Action* {
auto* act = new Action();
auto* act = global_arena->New<Action>();
act->value = LValAction({.exp = e});
return act;
}
auto Action::MakeExpressionAction(const Expression* e) -> Action* {
auto* act = new Action();
auto* act = global_arena->New<Action>();
act->value = ExpressionAction({.exp = e});
return act;
}
auto Action::MakePatternAction(const Pattern* p) -> Action* {
auto* act = new Action();
auto* act = global_arena->New<Action>();
act->value = PatternAction({.pattern = p});
return act;
}
auto Action::MakeStatementAction(const Statement* s) -> Action* {
auto* act = new Action();
auto* act = global_arena->New<Action>();
act->value = StatementAction({.stmt = s});
return act;
}
auto Action::MakeValAction(const Value* v) -> Action* {
auto* act = new Action();
auto* act = global_arena->New<Action>();
act->value = ValAction({.val = v});
return act;
}
@@ -10,6 +10,7 @@
#include <optional>
#include <string>
#include "executable_semantics/common/arena.h"
#include "executable_semantics/interpreter/list_node.h"
namespace Carbon {
@@ -37,7 +38,8 @@ class Dictionary {
// Associate the value v with key k in the dictionary.
// Time complexity: O(1).
auto Set(const K& k, const V& v) -> void {
head = new ListNode<std::pair<K, V>>(std::make_pair(k, v), head);
head = global_arena->New<ListNode<std::pair<K, V>>>(std::make_pair(k, v),
head);
}
typedef ListNodeIterator<std::pair<K, V>> Iterator;
@@ -14,6 +14,7 @@
#include "common/check.h"
#include "executable_semantics/ast/expression.h"
#include "executable_semantics/ast/function_definition.h"
#include "executable_semantics/common/arena.h"
#include "executable_semantics/common/error.h"
#include "executable_semantics/common/tracing_flag.h"
#include "executable_semantics/interpreter/action.h"
@@ -193,10 +194,11 @@ void CallFunction(int line_num, std::vector<const Value*> operas,
&params, line_num);
CHECK(matches) << "internal error in call_function, pattern match failed";
// Create the new frame and push it on the stack
auto* scope = new Scope(*matches, params);
auto* frame = new Frame(operas[0]->GetFunctionValue().name, Stack(scope),
Stack(Action::MakeStatementAction(
operas[0]->GetFunctionValue().body)));
auto* scope = global_arena->New<Scope>(*matches, params);
auto* frame = global_arena->New<Frame>(
operas[0]->GetFunctionValue().name, Stack(scope),
Stack(
Action::MakeStatementAction(operas[0]->GetFunctionValue().body)));
state->stack.Push(frame);
break;
}
@@ -888,7 +890,7 @@ void StepStmt() {
std::optional<Env> matches =
PatternMatch(pat, v, values, &vars, stmt->line_num);
if (matches) { // we have a match, start the body
auto* new_scope = new Scope(*matches, vars);
auto* new_scope = global_arena->New<Scope>(*matches, vars);
frame->scopes.Push(new_scope);
const Statement* body_block =
Statement::MakeBlock(stmt->line_num, c->second);
@@ -959,7 +961,8 @@ void StepStmt() {
case StatementKind::Block: {
if (act->pos == 0) {
if (stmt->GetBlock().stmt) {
auto* scope = new Scope(CurrentEnv(state), {});
auto* scope = global_arena->New<Scope>(CurrentEnv(state),
std::list<std::string>());
frame->scopes.Push(scope);
frame->todo.Push(Action::MakeStatementAction(stmt->GetBlock().stmt));
act->pos++;
@@ -1085,14 +1088,16 @@ void StepStmt() {
CHECK(act->pos == 0);
// Create a continuation object by creating a frame similar the
// way one is created in a function call.
Scope* scope = new Scope(CurrentEnv(state), std::list<std::string>());
Scope* scope =
global_arena->New<Scope>(CurrentEnv(state), std::list<std::string>());
Stack<Scope*> scopes;
scopes.Push(scope);
Stack<Action*> todo;
todo.Push(Action::MakeStatementAction(Statement::MakeReturn(
stmt->line_num, Expression::MakeTupleLiteral(stmt->line_num, {}))));
todo.Push(Action::MakeStatementAction(stmt->GetContinuation().body));
Frame* continuation_frame = new Frame("__continuation", scopes, todo);
Frame* continuation_frame =
global_arena->New<Frame>("__continuation", scopes, todo);
Address continuation_address = state->heap.AllocateValue(
Value::MakeContinuationValue({continuation_frame}));
// Store the continuation's address in the frame.
@@ -1176,7 +1181,7 @@ void Step() {
// Interpret the whole porogram.
auto InterpProgram(std::list<Declaration>* fs) -> int {
state = new State(); // Runtime state.
state = global_arena->New<State>(); // Runtime state.
if (tracing_output) {
llvm::outs() << "********** initializing globals **********\n";
}
@@ -1186,8 +1191,8 @@ auto InterpProgram(std::list<Declaration>* fs) -> int {
const Expression* call_main = Expression::MakeCallExpression(
0, Expression::MakeIdentifierExpression(0, "main"), arg);
auto todo = Stack(Action::MakeExpressionAction(call_main));
auto* scope = new Scope(globals, std::list<std::string>());
auto* frame = new Frame("top", Stack(scope), todo);
auto* scope = global_arena->New<Scope>(globals, std::list<std::string>());
auto* frame = global_arena->New<Frame>("top", Stack(scope), todo);
state->stack = Stack(frame);
if (tracing_output) {
@@ -1209,8 +1214,8 @@ auto InterpProgram(std::list<Declaration>* fs) -> int {
// Interpret an expression at compile-time.
auto InterpExp(Env values, const Expression* e) -> const Value* {
auto todo = Stack(Action::MakeExpressionAction(e));
auto* scope = new Scope(values, std::list<std::string>());
auto* frame = new Frame("InterpExp", Stack(scope), todo);
auto* scope = global_arena->New<Scope>(values, std::list<std::string>());
auto* frame = global_arena->New<Frame>("InterpExp", Stack(scope), todo);
state->stack = Stack(frame);
while (state->stack.Count() > 1 || state->stack.Top()->todo.Count() > 1 ||
@@ -1224,8 +1229,8 @@ auto InterpExp(Env values, const Expression* e) -> const Value* {
// Interpret a pattern at compile-time.
auto InterpPattern(Env values, const Pattern* p) -> const Value* {
auto todo = Stack(Action::MakePatternAction(p));
auto* scope = new Scope(values, std::list<std::string>());
auto* frame = new Frame("InterpPattern", Stack(scope), todo);
auto* scope = global_arena->New<Scope>(values, std::list<std::string>());
auto* frame = global_arena->New<Frame>("InterpPattern", Stack(scope), todo);
state->stack = Stack(frame);
while (state->stack.Count() > 1 || state->stack.Top()->todo.Count() > 1 ||
+15 -9
View File
@@ -12,6 +12,7 @@
#include "common/ostream.h"
#include "executable_semantics/ast/function_definition.h"
#include "executable_semantics/common/arena.h"
#include "executable_semantics/common/error.h"
#include "executable_semantics/common/tracing_flag.h"
#include "executable_semantics/interpreter/interpreter.h"
@@ -512,9 +513,10 @@ auto TypeCheckPattern(const Pattern* p, TypeEnv types, Env values,
FATAL_COMPILATION_ERROR(binding.LineNumber())
<< "Unsupported type pattern";
}
auto new_p = new BindingPattern(
auto new_p = global_arena->New<BindingPattern>(
binding.LineNumber(), binding.Name(),
new ExpressionPattern(ReifyType(type, binding.LineNumber())));
global_arena->New<ExpressionPattern>(
ReifyType(type, binding.LineNumber())));
if (binding.Name().has_value()) {
types.Set(*binding.Name(), type);
}
@@ -553,7 +555,8 @@ auto TypeCheckPattern(const Pattern* p, TypeEnv types, Env values,
TuplePattern::Field(field.name, field_result.pattern));
field_types.push_back({.name = field.name, .value = field_result.type});
}
auto new_tuple = new TuplePattern(tuple.LineNumber(), new_fields);
auto new_tuple =
global_arena->New<TuplePattern>(tuple.LineNumber(), new_fields);
auto tuple_t = Value::MakeTupleValue(std::move(field_types));
return {.pattern = new_tuple, .type = tuple_t, .types = new_types};
}
@@ -578,7 +581,7 @@ auto TypeCheckPattern(const Pattern* p, TypeEnv types, Env values,
}
TCPattern arg_results = TypeCheckPattern(alternative.Arguments(), types,
values, parameter_types);
return {.pattern = new AlternativePattern(
return {.pattern = global_arena->New<AlternativePattern>(
alternative.LineNumber(),
ReifyType(choice_type, alternative.LineNumber()),
alternative.AlternativeName(),
@@ -589,7 +592,7 @@ auto TypeCheckPattern(const Pattern* p, TypeEnv types, Env values,
case Pattern::Kind::ExpressionPattern: {
TCExpression result =
TypeCheckExp(cast<ExpressionPattern>(p)->Expression(), types, values);
return {.pattern = new ExpressionPattern(result.exp),
return {.pattern = global_arena->New<ExpressionPattern>(result.exp),
.type = result.type,
.types = result.types};
}
@@ -622,7 +625,8 @@ auto TypeCheckStmt(const Statement* s, TypeEnv types, Env values,
auto res = TypeCheckExp(s->GetMatch().exp, types, values);
auto res_type = res.type;
auto new_clauses =
new std::list<std::pair<const Pattern*, const Statement*>>();
global_arena
->New<std::list<std::pair<const Pattern*, const Statement*>>>();
for (auto& clause : *s->GetMatch().clauses) {
new_clauses->push_back(TypecheckCase(
res_type, clause.first, clause.second, types, values, ret_type));
@@ -748,7 +752,8 @@ auto CheckOrEnsureReturn(const Statement* stmt, bool void_return, int line_num)
switch (stmt->tag()) {
case StatementKind::Match: {
auto new_clauses =
new std::list<std::pair<const Pattern*, const Statement*>>();
global_arena
->New<std::list<std::pair<const Pattern*, const Statement*>>>();
for (auto i = stmt->GetMatch().clauses->begin();
i != stmt->GetMatch().clauses->end(); ++i) {
auto s = CheckOrEnsureReturn(i->second, void_return, stmt->line_num);
@@ -827,9 +832,10 @@ auto TypeCheckFunDef(const FunctionDefinition* f, TypeEnv types, Env values)
auto res = TypeCheckStmt(f->body, param_res.types, values, return_type);
bool void_return = TypeEqual(return_type, Value::MakeUnitTypeVal());
auto body = CheckOrEnsureReturn(res.stmt, void_return, f->line_num);
return new FunctionDefinition(
return global_arena->New<FunctionDefinition>(
f->line_num, f->name, f->deduced_parameters, f->param_pattern,
new ExpressionPattern(ReifyType(return_type, f->line_num)), body);
global_arena->New<ExpressionPattern>(ReifyType(return_type, f->line_num)),
body);
}
auto TypeOfFunDef(TypeEnv types, Env values, const FunctionDefinition* fun_def)
+22 -21
View File
@@ -7,6 +7,7 @@
#include <algorithm>
#include "common/check.h"
#include "executable_semantics/common/arena.h"
#include "executable_semantics/common/error.h"
#include "llvm/ADT/StringExtras.h"
@@ -111,47 +112,47 @@ auto TupleValue::FindField(const std::string& name) const -> const Value* {
}
auto Value::MakeIntValue(int i) -> const Value* {
auto* v = new Value();
auto* v = global_arena->New<Value>();
v->value = IntValue({.value = i});
return v;
}
auto Value::MakeBoolValue(bool b) -> const Value* {
auto* v = new Value();
auto* v = global_arena->New<Value>();
v->value = BoolValue({.value = b});
return v;
}
auto Value::MakeFunctionValue(std::string name, const Value* param,
const Statement* body) -> const Value* {
auto* v = new Value();
auto* v = global_arena->New<Value>();
v->value =
FunctionValue({.name = std::move(name), .param = param, .body = body});
return v;
}
auto Value::MakePointerValue(Address addr) -> const Value* {
auto* v = new Value();
auto* v = global_arena->New<Value>();
v->value = PointerValue({.value = addr});
return v;
}
auto Value::MakeStructValue(const Value* type, const Value* inits)
-> const Value* {
auto* v = new Value();
auto* v = global_arena->New<Value>();
v->value = StructValue({.type = type, .inits = inits});
return v;
}
auto Value::MakeTupleValue(std::vector<TupleElement> elements) -> const Value* {
auto* v = new Value();
auto* v = global_arena->New<Value>();
v->value = TupleValue({.elements = std::move(elements)});
return v;
}
auto Value::MakeAlternativeValue(std::string alt_name, std::string choice_name,
const Value* argument) -> const Value* {
auto* v = new Value();
auto* v = global_arena->New<Value>();
v->value = AlternativeValue({.alt_name = std::move(alt_name),
.choice_name = std::move(choice_name),
.argument = argument});
@@ -161,7 +162,7 @@ auto Value::MakeAlternativeValue(std::string alt_name, std::string choice_name,
auto Value::MakeAlternativeConstructorValue(std::string alt_name,
std::string choice_name)
-> const Value* {
auto* v = new Value();
auto* v = global_arena->New<Value>();
v->value = AlternativeConstructorValue(
{.alt_name = std::move(alt_name), .choice_name = std::move(choice_name)});
return v;
@@ -170,45 +171,45 @@ auto Value::MakeAlternativeConstructorValue(std::string alt_name,
// Return a first-class continuation represented a fragment
// of the stack.
auto Value::MakeContinuationValue(std::vector<Frame*> stack) -> Value* {
auto* v = new Value();
auto* v = global_arena->New<Value>();
v->value = ContinuationValue({.stack = std::move(stack)});
return v;
}
auto Value::MakeBindingPlaceholderValue(std::optional<std::string> name,
const Value* type) -> const Value* {
auto* v = new Value();
auto* v = global_arena->New<Value>();
v->value = BindingPlaceholderValue({.name = std::move(name), .type = type});
return v;
}
auto Value::MakeIntType() -> const Value* {
auto* v = new Value();
auto* v = global_arena->New<Value>();
v->value = IntType();
return v;
}
auto Value::MakeBoolType() -> const Value* {
auto* v = new Value();
auto* v = global_arena->New<Value>();
v->value = BoolType();
return v;
}
auto Value::MakeTypeType() -> const Value* {
auto* v = new Value();
auto* v = global_arena->New<Value>();
v->value = TypeType();
return v;
}
// Return a Continuation type.
auto Value::MakeContinuationType() -> const Value* {
auto* v = new Value();
auto* v = global_arena->New<Value>();
v->value = ContinuationType();
return v;
}
auto Value::MakeAutoType() -> const Value* {
auto* v = new Value();
auto* v = global_arena->New<Value>();
v->value = AutoType();
return v;
}
@@ -216,21 +217,21 @@ auto Value::MakeAutoType() -> const Value* {
auto Value::MakeFunctionType(std::vector<GenericBinding> deduced_params,
const Value* param, const Value* ret)
-> const Value* {
auto* v = new Value();
auto* v = global_arena->New<Value>();
v->value = FunctionType(
{.deduced = std::move(deduced_params), .param = param, .ret = ret});
return v;
}
auto Value::MakePointerType(const Value* type) -> const Value* {
auto* v = new Value();
auto* v = global_arena->New<Value>();
v->value = PointerType({.type = type});
return v;
}
auto Value::MakeStructType(std::string name, VarValues fields,
VarValues methods) -> const Value* {
auto* v = new Value();
auto* v = global_arena->New<Value>();
v->value = StructType({.name = std::move(name),
.fields = std::move(fields),
.methods = std::move(methods)});
@@ -238,20 +239,20 @@ auto Value::MakeStructType(std::string name, VarValues fields,
}
auto Value::MakeUnitTypeVal() -> const Value* {
auto* v = new Value();
auto* v = global_arena->New<Value>();
v->value = TupleValue({.elements = {}});
return v;
}
auto Value::MakeChoiceType(std::string name, VarValues alts) -> const Value* {
auto* v = new Value();
auto* v = global_arena->New<Value>();
v->value =
ChoiceType({.name = std::move(name), .alternatives = std::move(alts)});
return v;
}
auto Value::MakeVariableType(std::string name) -> const Value* {
auto* v = new Value();
auto* v = global_arena->New<Value>();
v->value = VariableType({.name = std::move(name)});
return v;
}
+1
View File
@@ -33,6 +33,7 @@ cc_library(
"//common:ostream",
"//executable_semantics/ast:declaration",
"//executable_semantics/ast:expression",
"//executable_semantics/common:arena",
"//executable_semantics/common:error",
"//executable_semantics/common:tracing_flag",
"//executable_semantics/interpreter",
+1 -4
View File
@@ -178,10 +178,7 @@ operator and its operand, leading to three more cases:
{identifier} {
BEGIN(AFTER_OPERAND);
int n = strlen(yytext);
auto r = reinterpret_cast<char*>(malloc((n + 1) * sizeof(char)));
strncpy(r, yytext, n + 1);
return yy::parser::make_identifier(r, context.current_token_position);
return yy::parser::make_identifier(yytext, context.current_token_position);
}
{integer_literal} {
+19 -17
View File
@@ -63,6 +63,7 @@
#include "executable_semantics/ast/expression.h"
#include "executable_semantics/ast/function_definition.h"
#include "executable_semantics/ast/pattern.h"
#include "executable_semantics/common/arena.h"
#include "executable_semantics/syntax/paren_contents.h"
namespace Carbon {
@@ -82,8 +83,8 @@ void yy::parser::error(const location_type&, const std::string& message) {
} // %code
%token <int> integer_literal
%token <char*> identifier
%type <char*> designator
%token <std::string> identifier
%type <std::string> designator
%type <Carbon::Declaration> declaration
%type <Carbon::FunctionDefinition> function_declaration
%type <Carbon::FunctionDefinition> function_definition
@@ -310,17 +311,17 @@ pattern:
non_expression_pattern
{ $$ = $1; }
| expression
{ $$ = new Carbon::ExpressionPattern($1); }
{ $$ = Carbon::global_arena->New<Carbon::ExpressionPattern>($1); }
;
non_expression_pattern:
AUTO
{ $$ = new Carbon::AutoPattern(yylineno); }
{ $$ = Carbon::global_arena->New<Carbon::AutoPattern>(yylineno); }
| binding_lhs ":" pattern
{ $$ = new Carbon::BindingPattern(yylineno, $1, $3); }
{ $$ = Carbon::global_arena->New<Carbon::BindingPattern>(yylineno, $1, $3); }
| paren_pattern
{ $$ = $1; }
| expression tuple_pattern
{ $$ = new Carbon::AlternativePattern(yylineno, $1, $2); }
{ $$ = Carbon::global_arena->New<Carbon::AlternativePattern>(yylineno, $1, $2); }
;
binding_lhs:
identifier { $$ = $1; }
@@ -354,7 +355,7 @@ paren_pattern_contents:
| paren_pattern_contents "," paren_expression_element
{
$$ = $1;
$$.elements.push_back({.name = $3.name, .term = new Carbon::ExpressionPattern($3.term)});
$$.elements.push_back({.name = $3.name, .term = Carbon::global_arena->New<Carbon::ExpressionPattern>($3.term)});
}
| paren_pattern_contents "," paren_pattern_element
{
@@ -376,24 +377,25 @@ tuple_pattern: paren_pattern_base
// rules out the possibility of an `expression` at this point.
maybe_empty_tuple_pattern:
"(" ")"
{ $$ = new Carbon::TuplePattern(yylineno, {}); }
{ $$ = Carbon::global_arena->New<Carbon::TuplePattern>(yylineno, std::vector<Carbon::TuplePattern::Field>()); }
| tuple_pattern
{ $$ = $1; }
;
clause:
CASE pattern DBLARROW statement
{ $$ = new std::pair<const Carbon::Pattern*, const Carbon::Statement*>($2, $4); }
{ $$ = Carbon::global_arena->New<std::pair<const Carbon::Pattern*, const Carbon::Statement*>>($2, $4); }
| DEFAULT DBLARROW statement
{
auto vp = new Carbon::BindingPattern(
yylineno, std::nullopt, new Carbon::AutoPattern(yylineno));
$$ = new std::pair<const Carbon::Pattern*, const Carbon::Statement*>(vp, $3);
auto vp = Carbon::global_arena->New<Carbon::BindingPattern>(
yylineno, std::nullopt, Carbon::global_arena->New<Carbon::AutoPattern>(yylineno));
$$ = Carbon::global_arena->New<std::pair<const Carbon::Pattern*, const Carbon::Statement*>>(vp, $3);
}
;
clause_list:
// Empty
{
$$ = new std::list<std::pair<const Carbon::Pattern*, const Carbon::Statement*>>();
$$ = Carbon::global_arena->New<std::list<
std::pair<const Carbon::Pattern*, const Carbon::Statement*>>>();
}
| clause clause_list
{ $$ = $2; $$->push_front(*$1); }
@@ -484,13 +486,13 @@ function_definition:
FN identifier deduced_params maybe_empty_tuple_pattern return_type block
{
$$ = Carbon::FunctionDefinition(
yylineno, $2, $3, $4, new Carbon::ExpressionPattern($5), $6);
yylineno, $2, $3, $4, Carbon::global_arena->New<Carbon::ExpressionPattern>($5), $6);
}
| FN identifier deduced_params maybe_empty_tuple_pattern DBLARROW expression ";"
{
$$ = Carbon::FunctionDefinition(
yylineno, $2, $3, $4,
new Carbon::AutoPattern(yylineno),
Carbon::global_arena->New<Carbon::AutoPattern>(yylineno),
Carbon::Statement::MakeReturn(yylineno, $6));
}
;
@@ -498,10 +500,10 @@ function_declaration:
FN identifier deduced_params maybe_empty_tuple_pattern return_type ";"
{
$$ = Carbon::FunctionDefinition(
yylineno, $2, $3, $4, new Carbon::ExpressionPattern($5), 0); }
yylineno, $2, $3, $4, Carbon::global_arena->New<Carbon::ExpressionPattern>($5), 0); }
;
variable_declaration: identifier ":" pattern
{ $$ = new Carbon::BindingPattern(yylineno, $1, $3); }
{ $$ = Carbon::global_arena->New<Carbon::BindingPattern>(yylineno, $1, $3); }
;
member: VAR variable_declaration ";"
{ $$ = Carbon::Member::MakeFieldMember(yylineno, $2); }
@@ -5,6 +5,7 @@
#include "executable_semantics/syntax/syntax_helpers.h"
#include "common/ostream.h"
#include "executable_semantics/common/arena.h"
#include "executable_semantics/common/tracing_flag.h"
#include "executable_semantics/interpreter/interpreter.h"
#include "executable_semantics/interpreter/typecheck.h"
@@ -19,7 +20,7 @@ void ExecProgram(std::list<Declaration>* fs) {
}
llvm::outs() << "********** type checking **********\n";
}
state = new State(); // Compile-time state.
state = global_arena->New<State>(); // Compile-time state.
TypeCheckContext p = TopLevel(fs);
TypeEnv top = p.types;
Env ct_top = p.values;
-4
View File
@@ -111,9 +111,6 @@ def _update_list(use_git_state):
def _update_golden(test):
"""Updates the golden file for `test` by running executable_semantics."""
# TODO(#580): Remove this when leaks are fixed.
env = os.environ.copy()
env["ASAN_OPTIONS"] = "detect_leaks=0"
# Invoke the test update directly in order to allow parallel execution
# (`bazel run` will serialize).
p = subprocess.run(
@@ -123,7 +120,6 @@ def _update_golden(test):
"%s/executable_semantics %s/%s.carbon" % (_BINDIR, _TESTDATA, test),
"--update",
],
env=env,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)