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>
diff --git a/src/ast/access_decoration.cc b/src/ast/access_decoration.cc
index 976ffe2..1d59be5 100644
--- a/src/ast/access_decoration.cc
+++ b/src/ast/access_decoration.cc
@@ -35,7 +35,9 @@
}
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
diff --git a/src/ast/array_accessor_expression.cc b/src/ast/array_accessor_expression.cc
index b8855b0..c0d7c09 100644
--- a/src/ast/array_accessor_expression.cc
+++ b/src/ast/array_accessor_expression.cc
@@ -34,8 +34,11 @@
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 {
diff --git a/src/ast/assignment_statement.cc b/src/ast/assignment_statement.cc
index aec1d64..9c8787e 100644
--- a/src/ast/assignment_statement.cc
+++ b/src/ast/assignment_statement.cc
@@ -32,8 +32,11 @@
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 {
diff --git a/src/ast/binary_expression.cc b/src/ast/binary_expression.cc
index c1fc0d6..980d035 100644
--- a/src/ast/binary_expression.cc
+++ b/src/ast/binary_expression.cc
@@ -33,8 +33,11 @@
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 {
diff --git a/src/ast/binding_decoration.cc b/src/ast/binding_decoration.cc
index a8714dc..b15f023 100644
--- a/src/ast/binding_decoration.cc
+++ b/src/ast/binding_decoration.cc
@@ -35,7 +35,9 @@
}
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
diff --git a/src/ast/bitcast_expression.cc b/src/ast/bitcast_expression.cc
index df28119..eecfe7e 100644
--- a/src/ast/bitcast_expression.cc
+++ b/src/ast/bitcast_expression.cc
@@ -31,8 +31,11 @@
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 {
diff --git a/src/ast/block_statement.cc b/src/ast/block_statement.cc
index 6e4b3f2..09ff97d 100644
--- a/src/ast/block_statement.cc
+++ b/src/ast/block_statement.cc
@@ -31,8 +31,10 @@
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 {
diff --git a/src/ast/bool_literal.cc b/src/ast/bool_literal.cc
index 9a9f180..1952456 100644
--- a/src/ast/bool_literal.cc
+++ b/src/ast/bool_literal.cc
@@ -36,8 +36,10 @@
}
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
diff --git a/src/ast/break_statement.cc b/src/ast/break_statement.cc
index 15a8e1c..59de3d4 100644
--- a/src/ast/break_statement.cc
+++ b/src/ast/break_statement.cc
@@ -29,7 +29,9 @@
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 {
diff --git a/src/ast/builtin_decoration.cc b/src/ast/builtin_decoration.cc
index e275752..02300b6 100644
--- a/src/ast/builtin_decoration.cc
+++ b/src/ast/builtin_decoration.cc
@@ -35,7 +35,9 @@
}
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
diff --git a/src/ast/call_expression.cc b/src/ast/call_expression.cc
index a54f9a7..d6a2c5a 100644
--- a/src/ast/call_expression.cc
+++ b/src/ast/call_expression.cc
@@ -32,8 +32,11 @@
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 {
diff --git a/src/ast/call_statement.cc b/src/ast/call_statement.cc
index 1e48538..97bc730 100644
--- a/src/ast/call_statement.cc
+++ b/src/ast/call_statement.cc
@@ -31,8 +31,10 @@
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 {
diff --git a/src/ast/case_statement.cc b/src/ast/case_statement.cc
index 5f5934d..a467999 100644
--- a/src/ast/case_statement.cc
+++ b/src/ast/case_statement.cc
@@ -32,8 +32,11 @@
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 {
diff --git a/src/ast/constant_id_decoration.cc b/src/ast/constant_id_decoration.cc
index fec8fe8..1fa9987 100644
--- a/src/ast/constant_id_decoration.cc
+++ b/src/ast/constant_id_decoration.cc
@@ -35,7 +35,9 @@
}
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
diff --git a/src/ast/continue_statement.cc b/src/ast/continue_statement.cc
index 3b066a4..5d3d7cb 100644
--- a/src/ast/continue_statement.cc
+++ b/src/ast/continue_statement.cc
@@ -29,7 +29,9 @@
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 {
diff --git a/src/ast/discard_statement.cc b/src/ast/discard_statement.cc
index ec2bf65..9deed12 100644
--- a/src/ast/discard_statement.cc
+++ b/src/ast/discard_statement.cc
@@ -29,7 +29,9 @@
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 {
diff --git a/src/ast/else_statement.cc b/src/ast/else_statement.cc
index 30e18a6..a80fe36 100644
--- a/src/ast/else_statement.cc
+++ b/src/ast/else_statement.cc
@@ -32,8 +32,11 @@
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 {
diff --git a/src/ast/fallthrough_statement.cc b/src/ast/fallthrough_statement.cc
index dcdc26a..ce1e715 100644
--- a/src/ast/fallthrough_statement.cc
+++ b/src/ast/fallthrough_statement.cc
@@ -30,7 +30,9 @@
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 {
diff --git a/src/ast/float_literal.cc b/src/ast/float_literal.cc
index f7b54f4..a99bec2 100644
--- a/src/ast/float_literal.cc
+++ b/src/ast/float_literal.cc
@@ -43,8 +43,10 @@
}
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
diff --git a/src/ast/function.cc b/src/ast/function.cc
index a2b5ef7..f93e1d6 100644
--- a/src/ast/function.cc
+++ b/src/ast/function.cc
@@ -70,9 +70,14 @@
}
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 {
diff --git a/src/ast/group_decoration.cc b/src/ast/group_decoration.cc
index 5c8171d..08a4107 100644
--- a/src/ast/group_decoration.cc
+++ b/src/ast/group_decoration.cc
@@ -35,7 +35,9 @@
}
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
diff --git a/src/ast/identifier_expression.cc b/src/ast/identifier_expression.cc
index ba05e64..c8c9fd1 100644
--- a/src/ast/identifier_expression.cc
+++ b/src/ast/identifier_expression.cc
@@ -30,8 +30,10 @@
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 {
diff --git a/src/ast/if_statement.cc b/src/ast/if_statement.cc
index 0b018ef..5ad49aa 100644
--- a/src/ast/if_statement.cc
+++ b/src/ast/if_statement.cc
@@ -37,10 +37,12 @@
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 {
diff --git a/src/ast/location_decoration.cc b/src/ast/location_decoration.cc
index 8e25036..4052819 100644
--- a/src/ast/location_decoration.cc
+++ b/src/ast/location_decoration.cc
@@ -35,7 +35,9 @@
}
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
diff --git a/src/ast/loop_statement.cc b/src/ast/loop_statement.cc
index 74cb698..9616499 100644
--- a/src/ast/loop_statement.cc
+++ b/src/ast/loop_statement.cc
@@ -32,8 +32,11 @@
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 {
diff --git a/src/ast/member_accessor_expression.cc b/src/ast/member_accessor_expression.cc
index e58ad98..be335f4 100644
--- a/src/ast/member_accessor_expression.cc
+++ b/src/ast/member_accessor_expression.cc
@@ -34,8 +34,11 @@
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 {
diff --git a/src/ast/null_literal.cc b/src/ast/null_literal.cc
index 835ae29..7ea8476 100644
--- a/src/ast/null_literal.cc
+++ b/src/ast/null_literal.cc
@@ -36,8 +36,10 @@
}
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
diff --git a/src/ast/return_statement.cc b/src/ast/return_statement.cc
index 2f85773..49bebbc 100644
--- a/src/ast/return_statement.cc
+++ b/src/ast/return_statement.cc
@@ -33,8 +33,10 @@
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 {
diff --git a/src/ast/scalar_constructor_expression.cc b/src/ast/scalar_constructor_expression.cc
index 4c90f19..61cad8f 100644
--- a/src/ast/scalar_constructor_expression.cc
+++ b/src/ast/scalar_constructor_expression.cc
@@ -33,8 +33,10 @@
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 {
diff --git a/src/ast/sint_literal.cc b/src/ast/sint_literal.cc
index 3c946ac..be82a94 100644
--- a/src/ast/sint_literal.cc
+++ b/src/ast/sint_literal.cc
@@ -36,8 +36,10 @@
}
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
diff --git a/src/ast/stage_decoration.cc b/src/ast/stage_decoration.cc
index bd68fe2..bb12dfe 100644
--- a/src/ast/stage_decoration.cc
+++ b/src/ast/stage_decoration.cc
@@ -35,7 +35,9 @@
}
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
diff --git a/src/ast/stride_decoration.cc b/src/ast/stride_decoration.cc
index 52f3ef5..282aea6 100644
--- a/src/ast/stride_decoration.cc
+++ b/src/ast/stride_decoration.cc
@@ -35,7 +35,9 @@
}
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
diff --git a/src/ast/struct.cc b/src/ast/struct.cc
index 0493e3a..451fc19 100644
--- a/src/ast/struct.cc
+++ b/src/ast/struct.cc
@@ -53,8 +53,11 @@
}
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 {
diff --git a/src/ast/struct_block_decoration.cc b/src/ast/struct_block_decoration.cc
index 5c69f81..87f5121 100644
--- a/src/ast/struct_block_decoration.cc
+++ b/src/ast/struct_block_decoration.cc
@@ -35,7 +35,9 @@
}
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
diff --git a/src/ast/struct_member.cc b/src/ast/struct_member.cc
index b6aa642..9fc39c5 100644
--- a/src/ast/struct_member.cc
+++ b/src/ast/struct_member.cc
@@ -55,9 +55,12 @@
}
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 {
diff --git a/src/ast/struct_member_offset_decoration.cc b/src/ast/struct_member_offset_decoration.cc
index 87f13a6..9444dc5 100644
--- a/src/ast/struct_member_offset_decoration.cc
+++ b/src/ast/struct_member_offset_decoration.cc
@@ -37,8 +37,9 @@
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
diff --git a/src/ast/switch_statement.cc b/src/ast/switch_statement.cc
index 89dc22d..67908a8 100644
--- a/src/ast/switch_statement.cc
+++ b/src/ast/switch_statement.cc
@@ -33,8 +33,11 @@
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 {
diff --git a/src/ast/type_constructor_expression.cc b/src/ast/type_constructor_expression.cc
index 532e0d0..778ecca 100644
--- a/src/ast/type_constructor_expression.cc
+++ b/src/ast/type_constructor_expression.cc
@@ -34,8 +34,11 @@
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 {
diff --git a/src/ast/uint_literal.cc b/src/ast/uint_literal.cc
index e9dd464..d46602b 100644
--- a/src/ast/uint_literal.cc
+++ b/src/ast/uint_literal.cc
@@ -36,8 +36,10 @@
}
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
diff --git a/src/ast/unary_op_expression.cc b/src/ast/unary_op_expression.cc
index 495e49a..e803c21 100644
--- a/src/ast/unary_op_expression.cc
+++ b/src/ast/unary_op_expression.cc
@@ -32,8 +32,10 @@
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 {
diff --git a/src/ast/variable.cc b/src/ast/variable.cc
index 40056a4..1dd1bfe 100644
--- a/src/ast/variable.cc
+++ b/src/ast/variable.cc
@@ -92,10 +92,13 @@
}
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 {
diff --git a/src/ast/variable_decl_statement.cc b/src/ast/variable_decl_statement.cc
index 2dd0a77..cf9c8d7 100644
--- a/src/ast/variable_decl_statement.cc
+++ b/src/ast/variable_decl_statement.cc
@@ -31,8 +31,10 @@
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 {
diff --git a/src/ast/workgroup_decoration.cc b/src/ast/workgroup_decoration.cc
index 0d49f10..8282a7c 100644
--- a/src/ast/workgroup_decoration.cc
+++ b/src/ast/workgroup_decoration.cc
@@ -47,8 +47,9 @@
}
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
diff --git a/src/transform/bound_array_accessors.cc b/src/transform/bound_array_accessors.cc
index b17a181..72799be 100644
--- a/src/transform/bound_array_accessors.cc
+++ b/src/transform/bound_array_accessors.cc
@@ -120,12 +120,14 @@
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
diff --git a/src/transform/first_index_offset.cc b/src/transform/first_index_offset.cc
index 4ed52ab..6afd9fd 100644
--- a/src/transform/first_index_offset.cc
+++ b/src/transform/first_index_offset.cc
@@ -67,14 +67,15 @@
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
diff --git a/src/transform/transform.cc b/src/transform/transform.cc
index b0c8db5..c037cdb 100644
--- a/src/transform/transform.cc
+++ b/src/transform/transform.cc
@@ -40,12 +40,16 @@
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
diff --git a/src/type/access_control_type.cc b/src/type/access_control_type.cc
index 4d96e89..19e938b 100644
--- a/src/type/access_control_type.cc
+++ b/src/type/access_control_type.cc
@@ -77,7 +77,9 @@
}
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
diff --git a/src/type/alias_type.cc b/src/type/alias_type.cc
index 95fffe2..1bb580c 100644
--- a/src/type/alias_type.cc
+++ b/src/type/alias_type.cc
@@ -50,7 +50,10 @@
}
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
diff --git a/src/type/array_type.cc b/src/type/array_type.cc
index 549b88f..aee68fa 100644
--- a/src/type/array_type.cc
+++ b/src/type/array_type.cc
@@ -109,8 +109,10 @@
}
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
diff --git a/src/type/matrix_type.cc b/src/type/matrix_type.cc
index c678f4e..0723543 100644
--- a/src/type/matrix_type.cc
+++ b/src/type/matrix_type.cc
@@ -63,7 +63,9 @@
}
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
diff --git a/src/type/multisampled_texture_type.cc b/src/type/multisampled_texture_type.cc
index f647016..4c0ec25 100644
--- a/src/type/multisampled_texture_type.cc
+++ b/src/type/multisampled_texture_type.cc
@@ -49,7 +49,9 @@
}
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
diff --git a/src/type/pointer_type.cc b/src/type/pointer_type.cc
index ec564ec..7dd3649 100644
--- a/src/type/pointer_type.cc
+++ b/src/type/pointer_type.cc
@@ -46,7 +46,9 @@
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
diff --git a/src/type/sampled_texture_type.cc b/src/type/sampled_texture_type.cc
index bd4fb5c..24c0863 100644
--- a/src/type/sampled_texture_type.cc
+++ b/src/type/sampled_texture_type.cc
@@ -47,7 +47,9 @@
}
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
diff --git a/src/type/storage_texture_type.cc b/src/type/storage_texture_type.cc
index 14f86aa..8c25055 100644
--- a/src/type/storage_texture_type.cc
+++ b/src/type/storage_texture_type.cc
@@ -163,8 +163,9 @@
}
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,
diff --git a/src/type/struct_type.cc b/src/type/struct_type.cc
index 05ba4c7..11a8711 100644
--- a/src/type/struct_type.cc
+++ b/src/type/struct_type.cc
@@ -87,7 +87,10 @@
}
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
diff --git a/src/type/vector_type.cc b/src/type/vector_type.cc
index 84cdf24..b141a87 100644
--- a/src/type/vector_type.cc
+++ b/src/type/vector_type.cc
@@ -59,7 +59,9 @@
}
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