Cloning: move arguments to create() into temporary locals

In C++ argument evaluation order is undefined. MSVC and Clang evaluate these in different orders, leading to hilarity when writing tests that expect a deterministic ordering.

Pull out all the argument expressions to create() in the clone functions so a cloned program is deterministic in its ordering between compilers.

Change-Id: I8e2de31398960c480ce7ee1dfaac4f67652d2dbc
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/41544
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Auto-Submit: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton 2021-02-11 20:27:14 +00:00 committed by Commit Bot service account
parent 7b6bcb6e0b
commit 545c9742d5
56 changed files with 237 additions and 108 deletions

View File

@ -35,7 +35,9 @@ void AccessDecoration::to_str(const semantic::Info&,
}
AccessDecoration* AccessDecoration::Clone(CloneContext* ctx) const {
return ctx->dst->create<AccessDecoration>(ctx->Clone(source()), value_);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
return ctx->dst->create<AccessDecoration>(src, value_);
}
} // namespace ast

View File

@ -34,8 +34,11 @@ ArrayAccessorExpression::~ArrayAccessorExpression() = default;
ArrayAccessorExpression* ArrayAccessorExpression::Clone(
CloneContext* ctx) const {
return ctx->dst->create<ArrayAccessorExpression>(
ctx->Clone(source()), ctx->Clone(array_), ctx->Clone(idx_expr_));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto* arr = ctx->Clone(array_);
auto* idx = ctx->Clone(idx_expr_);
return ctx->dst->create<ArrayAccessorExpression>(src, arr, idx);
}
bool ArrayAccessorExpression::IsValid() const {

View File

@ -32,8 +32,11 @@ AssignmentStatement::AssignmentStatement(AssignmentStatement&&) = default;
AssignmentStatement::~AssignmentStatement() = default;
AssignmentStatement* AssignmentStatement::Clone(CloneContext* ctx) const {
return ctx->dst->create<AssignmentStatement>(
ctx->Clone(source()), ctx->Clone(lhs_), ctx->Clone(rhs_));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto* l = ctx->Clone(lhs_);
auto* r = ctx->Clone(rhs_);
return ctx->dst->create<AssignmentStatement>(src, l, r);
}
bool AssignmentStatement::IsValid() const {

View File

@ -33,8 +33,11 @@ BinaryExpression::BinaryExpression(BinaryExpression&&) = default;
BinaryExpression::~BinaryExpression() = default;
BinaryExpression* BinaryExpression::Clone(CloneContext* ctx) const {
return ctx->dst->create<BinaryExpression>(ctx->Clone(source()), op_,
ctx->Clone(lhs_), ctx->Clone(rhs_));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto* l = ctx->Clone(lhs_);
auto* r = ctx->Clone(rhs_);
return ctx->dst->create<BinaryExpression>(src, op_, l, r);
}
bool BinaryExpression::IsValid() const {

View File

@ -35,7 +35,9 @@ void BindingDecoration::to_str(const semantic::Info&,
}
BindingDecoration* BindingDecoration::Clone(CloneContext* ctx) const {
return ctx->dst->create<BindingDecoration>(ctx->Clone(source()), value_);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
return ctx->dst->create<BindingDecoration>(src, value_);
}
} // namespace ast

View File

@ -31,8 +31,11 @@ BitcastExpression::BitcastExpression(BitcastExpression&&) = default;
BitcastExpression::~BitcastExpression() = default;
BitcastExpression* BitcastExpression::Clone(CloneContext* ctx) const {
return ctx->dst->create<BitcastExpression>(
ctx->Clone(source()), ctx->Clone(type_), ctx->Clone(expr_));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto* ty = ctx->Clone(type_);
auto* e = ctx->Clone(expr_);
return ctx->dst->create<BitcastExpression>(src, ty, e);
}
bool BitcastExpression::IsValid() const {

View File

@ -31,8 +31,10 @@ BlockStatement::BlockStatement(BlockStatement&&) = default;
BlockStatement::~BlockStatement() = default;
BlockStatement* BlockStatement::Clone(CloneContext* ctx) const {
return ctx->dst->create<BlockStatement>(ctx->Clone(source()),
ctx->Clone(statements_));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto stmts = ctx->Clone(statements_);
return ctx->dst->create<BlockStatement>(src, stmts);
}
bool BlockStatement::IsValid() const {

View File

@ -36,8 +36,10 @@ std::string BoolLiteral::name() const {
}
BoolLiteral* BoolLiteral::Clone(CloneContext* ctx) const {
return ctx->dst->create<BoolLiteral>(ctx->Clone(source()), ctx->Clone(type()),
value_);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto* ty = ctx->Clone(type());
return ctx->dst->create<BoolLiteral>(src, ty, value_);
}
} // namespace ast

View File

@ -29,7 +29,9 @@ BreakStatement::BreakStatement(BreakStatement&&) = default;
BreakStatement::~BreakStatement() = default;
BreakStatement* BreakStatement::Clone(CloneContext* ctx) const {
return ctx->dst->create<BreakStatement>(ctx->Clone(source()));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
return ctx->dst->create<BreakStatement>(src);
}
bool BreakStatement::IsValid() const {

View File

@ -35,7 +35,9 @@ void BuiltinDecoration::to_str(const semantic::Info&,
}
BuiltinDecoration* BuiltinDecoration::Clone(CloneContext* ctx) const {
return ctx->dst->create<BuiltinDecoration>(ctx->Clone(source()), builtin_);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
return ctx->dst->create<BuiltinDecoration>(src, builtin_);
}
} // namespace ast

View File

@ -32,8 +32,11 @@ CallExpression::CallExpression(CallExpression&&) = default;
CallExpression::~CallExpression() = default;
CallExpression* CallExpression::Clone(CloneContext* ctx) const {
return ctx->dst->create<CallExpression>(
ctx->Clone(source()), ctx->Clone(func_), ctx->Clone(params_));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto* fn = ctx->Clone(func_);
auto p = ctx->Clone(params_);
return ctx->dst->create<CallExpression>(src, fn, p);
}
bool CallExpression::IsValid() const {

View File

@ -31,8 +31,10 @@ CallStatement::CallStatement(CallStatement&&) = default;
CallStatement::~CallStatement() = default;
CallStatement* CallStatement::Clone(CloneContext* ctx) const {
return ctx->dst->create<CallStatement>(ctx->Clone(source()),
ctx->Clone(call_));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto* call = ctx->Clone(call_);
return ctx->dst->create<CallStatement>(src, call);
}
bool CallStatement::IsValid() const {

View File

@ -32,8 +32,11 @@ CaseStatement::CaseStatement(CaseStatement&&) = default;
CaseStatement::~CaseStatement() = default;
CaseStatement* CaseStatement::Clone(CloneContext* ctx) const {
return ctx->dst->create<CaseStatement>(
ctx->Clone(source()), ctx->Clone(selectors_), ctx->Clone(body_));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto sel = ctx->Clone(selectors_);
auto* b = ctx->Clone(body_);
return ctx->dst->create<CaseStatement>(src, sel, b);
}
bool CaseStatement::IsValid() const {

View File

@ -35,7 +35,9 @@ void ConstantIdDecoration::to_str(const semantic::Info&,
}
ConstantIdDecoration* ConstantIdDecoration::Clone(CloneContext* ctx) const {
return ctx->dst->create<ConstantIdDecoration>(ctx->Clone(source()), value_);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
return ctx->dst->create<ConstantIdDecoration>(src, value_);
}
} // namespace ast

View File

@ -29,7 +29,9 @@ ContinueStatement::ContinueStatement(ContinueStatement&&) = default;
ContinueStatement::~ContinueStatement() = default;
ContinueStatement* ContinueStatement::Clone(CloneContext* ctx) const {
return ctx->dst->create<ContinueStatement>(ctx->Clone(source()));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
return ctx->dst->create<ContinueStatement>(src);
}
bool ContinueStatement::IsValid() const {

View File

@ -29,7 +29,9 @@ DiscardStatement::DiscardStatement(DiscardStatement&&) = default;
DiscardStatement::~DiscardStatement() = default;
DiscardStatement* DiscardStatement::Clone(CloneContext* ctx) const {
return ctx->dst->create<DiscardStatement>(ctx->Clone(source()));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
return ctx->dst->create<DiscardStatement>(src);
}
bool DiscardStatement::IsValid() const {

View File

@ -32,8 +32,11 @@ ElseStatement::ElseStatement(ElseStatement&&) = default;
ElseStatement::~ElseStatement() = default;
ElseStatement* ElseStatement::Clone(CloneContext* ctx) const {
return ctx->dst->create<ElseStatement>(
ctx->Clone(source()), ctx->Clone(condition_), ctx->Clone(body_));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto* cond = ctx->Clone(condition_);
auto* b = ctx->Clone(body_);
return ctx->dst->create<ElseStatement>(src, cond, b);
}
bool ElseStatement::IsValid() const {

View File

@ -30,7 +30,9 @@ FallthroughStatement::FallthroughStatement(FallthroughStatement&&) = default;
FallthroughStatement::~FallthroughStatement() = default;
FallthroughStatement* FallthroughStatement::Clone(CloneContext* ctx) const {
return ctx->dst->create<FallthroughStatement>(ctx->Clone(source()));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
return ctx->dst->create<FallthroughStatement>(src);
}
bool FallthroughStatement::IsValid() const {

View File

@ -43,8 +43,10 @@ std::string FloatLiteral::name() const {
}
FloatLiteral* FloatLiteral::Clone(CloneContext* ctx) const {
return ctx->dst->create<FloatLiteral>(ctx->Clone(source()),
ctx->Clone(type()), value_);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto* ty = ctx->Clone(type());
return ctx->dst->create<FloatLiteral>(src, ty, value_);
}
} // namespace ast

View File

@ -70,9 +70,14 @@ const Statement* Function::get_last_statement() const {
}
Function* Function::Clone(CloneContext* ctx) const {
return ctx->dst->create<Function>(
ctx->Clone(source()), ctx->Clone(symbol()), ctx->Clone(params_),
ctx->Clone(return_type_), ctx->Clone(body_), ctx->Clone(decorations_));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto sym = ctx->Clone(symbol());
auto p = ctx->Clone(params_);
auto* ret = ctx->Clone(return_type_);
auto* b = ctx->Clone(body_);
auto decos = ctx->Clone(decorations_);
return ctx->dst->create<Function>(src, sym, p, ret, b, decos);
}
bool Function::IsValid() const {

View File

@ -35,7 +35,9 @@ void GroupDecoration::to_str(const semantic::Info&,
}
GroupDecoration* GroupDecoration::Clone(CloneContext* ctx) const {
return ctx->dst->create<GroupDecoration>(ctx->Clone(source()), value_);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
return ctx->dst->create<GroupDecoration>(src, value_);
}
} // namespace ast

View File

@ -30,8 +30,10 @@ IdentifierExpression::IdentifierExpression(IdentifierExpression&&) = default;
IdentifierExpression::~IdentifierExpression() = default;
IdentifierExpression* IdentifierExpression::Clone(CloneContext* ctx) const {
return ctx->dst->create<IdentifierExpression>(ctx->Clone(source()),
ctx->Clone(symbol()));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto sym = ctx->Clone(symbol());
return ctx->dst->create<IdentifierExpression>(src, sym);
}
bool IdentifierExpression::IsValid() const {

View File

@ -37,10 +37,12 @@ IfStatement::IfStatement(IfStatement&&) = default;
IfStatement::~IfStatement() = default;
IfStatement* IfStatement::Clone(CloneContext* ctx) const {
auto* cloned = ctx->dst->create<IfStatement>(
ctx->Clone(source()), ctx->Clone(condition_), ctx->Clone(body_),
ctx->Clone(else_statements_));
return cloned;
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto* cond = ctx->Clone(condition_);
auto* b = ctx->Clone(body_);
auto el = ctx->Clone(else_statements_);
return ctx->dst->create<IfStatement>(src, cond, b, el);
}
bool IfStatement::IsValid() const {

View File

@ -35,7 +35,9 @@ void LocationDecoration::to_str(const semantic::Info&,
}
LocationDecoration* LocationDecoration::Clone(CloneContext* ctx) const {
return ctx->dst->create<LocationDecoration>(ctx->Clone(source()), value_);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
return ctx->dst->create<LocationDecoration>(src, value_);
}
} // namespace ast

View File

@ -32,8 +32,11 @@ LoopStatement::LoopStatement(LoopStatement&&) = default;
LoopStatement::~LoopStatement() = default;
LoopStatement* LoopStatement::Clone(CloneContext* ctx) const {
return ctx->dst->create<LoopStatement>(
ctx->Clone(source()), ctx->Clone(body_), ctx->Clone(continuing_));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto* b = ctx->Clone(body_);
auto* cont = ctx->Clone(continuing_);
return ctx->dst->create<LoopStatement>(src, b, cont);
}
bool LoopStatement::IsValid() const {

View File

@ -34,8 +34,11 @@ MemberAccessorExpression::~MemberAccessorExpression() = default;
MemberAccessorExpression* MemberAccessorExpression::Clone(
CloneContext* ctx) const {
return ctx->dst->create<MemberAccessorExpression>(
ctx->Clone(source()), ctx->Clone(struct_), ctx->Clone(member_));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto* str = ctx->Clone(structure());
auto* mem = ctx->Clone(member());
return ctx->dst->create<MemberAccessorExpression>(src, str, mem);
}
bool MemberAccessorExpression::IsValid() const {

View File

@ -36,8 +36,10 @@ std::string NullLiteral::name() const {
}
NullLiteral* NullLiteral::Clone(CloneContext* ctx) const {
return ctx->dst->create<NullLiteral>(ctx->Clone(source()),
ctx->Clone(type()));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto* ty = ctx->Clone(type());
return ctx->dst->create<NullLiteral>(src, ty);
}
} // namespace ast

View File

@ -33,8 +33,10 @@ ReturnStatement::ReturnStatement(ReturnStatement&&) = default;
ReturnStatement::~ReturnStatement() = default;
ReturnStatement* ReturnStatement::Clone(CloneContext* ctx) const {
return ctx->dst->create<ReturnStatement>(ctx->Clone(source()),
ctx->Clone(value_));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto* ret = ctx->Clone(value());
return ctx->dst->create<ReturnStatement>(src, ret);
}
bool ReturnStatement::IsValid() const {

View File

@ -33,8 +33,10 @@ ScalarConstructorExpression::~ScalarConstructorExpression() = default;
ScalarConstructorExpression* ScalarConstructorExpression::Clone(
CloneContext* ctx) const {
return ctx->dst->create<ScalarConstructorExpression>(ctx->Clone(source()),
ctx->Clone(literal_));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto* lit = ctx->Clone(literal());
return ctx->dst->create<ScalarConstructorExpression>(src, lit);
}
bool ScalarConstructorExpression::IsValid() const {

View File

@ -36,8 +36,10 @@ std::string SintLiteral::name() const {
}
SintLiteral* SintLiteral::Clone(CloneContext* ctx) const {
return ctx->dst->create<SintLiteral>(ctx->Clone(source()), ctx->Clone(type()),
value_);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto* ty = ctx->Clone(type());
return ctx->dst->create<SintLiteral>(src, ty, value_);
}
} // namespace ast

View File

@ -35,7 +35,9 @@ void StageDecoration::to_str(const semantic::Info&,
}
StageDecoration* StageDecoration::Clone(CloneContext* ctx) const {
return ctx->dst->create<StageDecoration>(ctx->Clone(source()), stage_);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
return ctx->dst->create<StageDecoration>(src, stage_);
}
} // namespace ast

View File

@ -35,7 +35,9 @@ void StrideDecoration::to_str(const semantic::Info&,
}
StrideDecoration* StrideDecoration::Clone(CloneContext* ctx) const {
return ctx->dst->create<StrideDecoration>(ctx->Clone(source()), stride_);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
return ctx->dst->create<StrideDecoration>(src, stride_);
}
} // namespace ast

View File

@ -53,8 +53,11 @@ bool Struct::IsBlockDecorated() const {
}
Struct* Struct::Clone(CloneContext* ctx) const {
return ctx->dst->create<Struct>(ctx->Clone(source()), ctx->Clone(members_),
ctx->Clone(decorations_));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto mem = ctx->Clone(members());
auto decos = ctx->Clone(decorations());
return ctx->dst->create<Struct>(src, mem, decos);
}
bool Struct::IsValid() const {

View File

@ -35,7 +35,9 @@ void StructBlockDecoration::to_str(const semantic::Info&,
}
StructBlockDecoration* StructBlockDecoration::Clone(CloneContext* ctx) const {
return ctx->dst->create<StructBlockDecoration>(ctx->Clone(source()));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
return ctx->dst->create<StructBlockDecoration>(src);
}
} // namespace ast

View File

@ -55,9 +55,12 @@ uint32_t StructMember::offset() const {
}
StructMember* StructMember::Clone(CloneContext* ctx) const {
return ctx->dst->create<StructMember>(ctx->Clone(source()),
ctx->Clone(symbol_), ctx->Clone(type_),
ctx->Clone(decorations_));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto sym = ctx->Clone(symbol_);
auto* ty = ctx->Clone(type_);
auto decos = ctx->Clone(decorations_);
return ctx->dst->create<StructMember>(src, sym, ty, decos);
}
bool StructMember::IsValid() const {

View File

@ -37,8 +37,9 @@ void StructMemberOffsetDecoration::to_str(const semantic::Info&,
StructMemberOffsetDecoration* StructMemberOffsetDecoration::Clone(
CloneContext* ctx) const {
return ctx->dst->create<StructMemberOffsetDecoration>(ctx->Clone(source()),
offset_);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
return ctx->dst->create<StructMemberOffsetDecoration>(src, offset_);
}
} // namespace ast

View File

@ -33,8 +33,11 @@ SwitchStatement::SwitchStatement(SwitchStatement&&) = default;
SwitchStatement::~SwitchStatement() = default;
SwitchStatement* SwitchStatement::Clone(CloneContext* ctx) const {
return ctx->dst->create<SwitchStatement>(
ctx->Clone(source()), ctx->Clone(condition_), ctx->Clone(body_));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto* cond = ctx->Clone(condition());
auto b = ctx->Clone(body());
return ctx->dst->create<SwitchStatement>(src, cond, b);
}
bool SwitchStatement::IsValid() const {

View File

@ -34,8 +34,11 @@ TypeConstructorExpression::~TypeConstructorExpression() = default;
TypeConstructorExpression* TypeConstructorExpression::Clone(
CloneContext* ctx) const {
return ctx->dst->create<TypeConstructorExpression>(
ctx->Clone(source()), ctx->Clone(type_), ctx->Clone(values_));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto* ty = ctx->Clone(type());
auto vals = ctx->Clone(values());
return ctx->dst->create<TypeConstructorExpression>(src, ty, vals);
}
bool TypeConstructorExpression::IsValid() const {

View File

@ -36,8 +36,10 @@ std::string UintLiteral::name() const {
}
UintLiteral* UintLiteral::Clone(CloneContext* ctx) const {
return ctx->dst->create<UintLiteral>(ctx->Clone(source()), ctx->Clone(type()),
value_);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto* ty = ctx->Clone(type());
return ctx->dst->create<UintLiteral>(src, ty, value_);
}
} // namespace ast

View File

@ -32,8 +32,10 @@ UnaryOpExpression::UnaryOpExpression(UnaryOpExpression&&) = default;
UnaryOpExpression::~UnaryOpExpression() = default;
UnaryOpExpression* UnaryOpExpression::Clone(CloneContext* ctx) const {
return ctx->dst->create<UnaryOpExpression>(ctx->Clone(source()), op_,
ctx->Clone(expr_));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto* e = ctx->Clone(expr());
return ctx->dst->create<UnaryOpExpression>(src, op_, e);
}
bool UnaryOpExpression::IsValid() const {

View File

@ -92,10 +92,13 @@ uint32_t Variable::constant_id() const {
}
Variable* Variable::Clone(CloneContext* ctx) const {
return ctx->dst->create<Variable>(
ctx->Clone(source()), ctx->Clone(symbol_), declared_storage_class(),
ctx->Clone(type()), is_const_, ctx->Clone(constructor()),
ctx->Clone(decorations_));
auto src = ctx->Clone(source());
auto sym = ctx->Clone(symbol());
auto* ty = ctx->Clone(type());
auto* ctor = ctx->Clone(constructor());
auto decos = ctx->Clone(decorations());
return ctx->dst->create<Variable>(src, sym, declared_storage_class(), ty,
is_const_, ctor, decos);
}
bool Variable::IsValid() const {

View File

@ -31,8 +31,10 @@ VariableDeclStatement::VariableDeclStatement(VariableDeclStatement&&) = default;
VariableDeclStatement::~VariableDeclStatement() = default;
VariableDeclStatement* VariableDeclStatement::Clone(CloneContext* ctx) const {
return ctx->dst->create<VariableDeclStatement>(ctx->Clone(source()),
ctx->Clone(variable_));
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
auto* var = ctx->Clone(variable());
return ctx->dst->create<VariableDeclStatement>(src, var);
}
bool VariableDeclStatement::IsValid() const {

View File

@ -47,8 +47,9 @@ void WorkgroupDecoration::to_str(const semantic::Info&,
}
WorkgroupDecoration* WorkgroupDecoration::Clone(CloneContext* ctx) const {
return ctx->dst->create<WorkgroupDecoration>(ctx->Clone(source()), x_, y_,
z_);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(source());
return ctx->dst->create<WorkgroupDecoration>(src, x_, y_, z_);
}
} // namespace ast

View File

@ -120,12 +120,14 @@ ast::ArrayAccessorExpression* BoundArrayAccessors::Transform(
return nullptr;
}
} else {
new_idx =
b.Call("min", b.Construct<u32>(ctx->Clone(old_idx)), b.Expr(size - 1));
auto* cloned_idx = ctx->Clone(old_idx);
new_idx = b.Call("min", b.Construct<u32>(cloned_idx), b.Expr(size - 1));
}
return b.create<ast::ArrayAccessorExpression>(
ctx->Clone(expr->source()), ctx->Clone(expr->array()), new_idx);
// Clone arguments outside of create() call to have deterministic ordering
auto src = ctx->Clone(expr->source());
auto* arr = ctx->Clone(expr->array());
return b.create<ast::ArrayAccessorExpression>(src, arr, new_idx);
}
} // namespace transform

View File

@ -67,14 +67,15 @@ constexpr char kIndexOffsetPrefix[] = "tint_first_index_offset_";
ast::Variable* clone_variable_with_new_name(CloneContext* ctx,
ast::Variable* in,
std::string new_name) {
// Clone arguments outside of create() call to have deterministic ordering
auto source = ctx->Clone(in->source());
auto symbol = ctx->dst->Symbols().Register(new_name);
auto* type = ctx->Clone(in->type());
auto* constructor = ctx->Clone(in->constructor());
auto decorations = ctx->Clone(in->decorations());
return ctx->dst->create<ast::Variable>(
ctx->Clone(in->source()), // source
ctx->dst->Symbols().Register(new_name), // symbol
in->declared_storage_class(), // declared_storage_class
ctx->Clone(in->type()), // type
in->is_const(), // is_const
ctx->Clone(in->constructor()), // constructor
ctx->Clone(in->decorations())); // decorations
source, symbol, in->declared_storage_class(), type, in->is_const(),
constructor, decorations);
}
} // namespace

View File

@ -40,12 +40,16 @@ ast::Function* Transform::CloneWithStatementsAtStart(
for (auto* s : *in->body()) {
statements.emplace_back(ctx->Clone(s));
}
return ctx->dst->create<ast::Function>(
ctx->Clone(in->source()), ctx->Clone(in->symbol()),
ctx->Clone(in->params()), ctx->Clone(in->return_type()),
ctx->dst->create<ast::BlockStatement>(ctx->Clone(in->body()->source()),
statements),
ctx->Clone(in->decorations()));
// Clone arguments outside of create() call to have deterministic ordering
auto source = ctx->Clone(in->source());
auto symbol = ctx->Clone(in->symbol());
auto params = ctx->Clone(in->params());
auto* return_type = ctx->Clone(in->return_type());
auto* body = ctx->dst->create<ast::BlockStatement>(
ctx->Clone(in->body()->source()), statements);
auto decos = ctx->Clone(in->decorations());
return ctx->dst->create<ast::Function>(source, symbol, params, return_type,
body, decos);
}
} // namespace transform

View File

@ -77,7 +77,9 @@ uint64_t AccessControl::BaseAlignment(MemoryLayout mem_layout) const {
}
AccessControl* AccessControl::Clone(CloneContext* ctx) const {
return ctx->dst->create<AccessControl>(access_, ctx->Clone(subtype_));
// Clone arguments outside of create() call to have deterministic ordering
auto* ty = ctx->Clone(type());
return ctx->dst->create<AccessControl>(access_, ty);
}
} // namespace type

View File

@ -50,7 +50,10 @@ uint64_t Alias::BaseAlignment(MemoryLayout mem_layout) const {
}
Alias* Alias::Clone(CloneContext* ctx) const {
return ctx->dst->create<Alias>(ctx->Clone(symbol()), ctx->Clone(subtype_));
// Clone arguments outside of create() call to have deterministic ordering
auto sym = ctx->Clone(symbol());
auto* ty = ctx->Clone(type());
return ctx->dst->create<Alias>(sym, ty);
}
} // namespace type

View File

@ -109,8 +109,10 @@ std::string Array::FriendlyName(const SymbolTable& symbols) const {
}
Array* Array::Clone(CloneContext* ctx) const {
return ctx->dst->create<Array>(ctx->Clone(subtype_), size_,
ctx->Clone(decorations()));
// Clone arguments outside of create() call to have deterministic ordering
auto* ty = ctx->Clone(type());
auto decos = ctx->Clone(decorations());
return ctx->dst->create<Array>(ty, size_, decos);
}
} // namespace type

View File

@ -63,7 +63,9 @@ uint64_t Matrix::BaseAlignment(MemoryLayout mem_layout) const {
}
Matrix* Matrix::Clone(CloneContext* ctx) const {
return ctx->dst->create<Matrix>(ctx->Clone(subtype_), rows_, columns_);
// Clone arguments outside of create() call to have deterministic ordering
auto* ty = ctx->Clone(type());
return ctx->dst->create<Matrix>(ty, rows_, columns_);
}
} // namespace type

View File

@ -49,7 +49,9 @@ std::string MultisampledTexture::FriendlyName(
}
MultisampledTexture* MultisampledTexture::Clone(CloneContext* ctx) const {
return ctx->dst->create<MultisampledTexture>(dim(), ctx->Clone(type_));
// Clone arguments outside of create() call to have deterministic ordering
auto* ty = ctx->Clone(type());
return ctx->dst->create<MultisampledTexture>(dim(), ty);
}
} // namespace type

View File

@ -46,7 +46,9 @@ Pointer::Pointer(Pointer&&) = default;
Pointer::~Pointer() = default;
Pointer* Pointer::Clone(CloneContext* ctx) const {
return ctx->dst->create<Pointer>(ctx->Clone(subtype_), storage_class_);
// Clone arguments outside of create() call to have deterministic ordering
auto* ty = ctx->Clone(type());
return ctx->dst->create<Pointer>(ty, storage_class_);
}
} // namespace type

View File

@ -47,7 +47,9 @@ std::string SampledTexture::FriendlyName(const SymbolTable& symbols) const {
}
SampledTexture* SampledTexture::Clone(CloneContext* ctx) const {
return ctx->dst->create<SampledTexture>(dim(), ctx->Clone(type_));
// Clone arguments outside of create() call to have deterministic ordering
auto* ty = ctx->Clone(type());
return ctx->dst->create<SampledTexture>(dim(), ty);
}
} // namespace type

View File

@ -163,8 +163,9 @@ std::string StorageTexture::FriendlyName(const SymbolTable&) const {
}
StorageTexture* StorageTexture::Clone(CloneContext* ctx) const {
return ctx->dst->create<StorageTexture>(dim(), image_format_,
ctx->Clone(subtype_));
// Clone arguments outside of create() call to have deterministic ordering
auto* ty = ctx->Clone(type());
return ctx->dst->create<StorageTexture>(dim(), image_format_, ty);
}
type::Type* StorageTexture::SubtypeFor(type::ImageFormat format,

View File

@ -87,7 +87,10 @@ uint64_t Struct::BaseAlignment(MemoryLayout mem_layout) const {
}
Struct* Struct::Clone(CloneContext* ctx) const {
return ctx->dst->create<Struct>(ctx->Clone(symbol()), ctx->Clone(struct_));
// Clone arguments outside of create() call to have deterministic ordering
auto sym = ctx->Clone(symbol());
auto* str = ctx->Clone(impl());
return ctx->dst->create<Struct>(sym, str);
}
} // namespace type

View File

@ -59,7 +59,9 @@ uint64_t Vector::BaseAlignment(MemoryLayout mem_layout) const {
}
Vector* Vector::Clone(CloneContext* ctx) const {
return ctx->dst->create<Vector>(ctx->Clone(subtype_), size_);
// Clone arguments outside of create() call to have deterministic ordering
auto* ty = ctx->Clone(type());
return ctx->dst->create<Vector>(ty, size_);
}
} // namespace type