Fix sem::Swizzle::HasSideEffects() not returning true when structure has side-effects
E.g. sem info for "f().x" returned false for HasSideEffects().
Bug: tint:1300
Change-Id: I789f75eef834c58a93e07d93c8334635d39981c3
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/83100
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: James Price <jrprice@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc
index d7c13a6..5c7e36a 100644
--- a/src/tint/resolver/resolver.cc
+++ b/src/tint/resolver/resolver.cc
@@ -1715,6 +1715,10 @@
const sem::Type* ret = nullptr;
std::vector<uint32_t> swizzle;
+ // Structure may be a side-effecting expression (e.g. function call).
+ auto* sem_structure = Sem(expr->structure);
+ bool has_side_effects = sem_structure && sem_structure->HasSideEffects();
+
if (auto* str = storage_ty->As<sem::Struct>()) {
Mark(expr->member);
auto symbol = expr->member->symbol;
@@ -1741,10 +1745,6 @@
ref->Access());
}
- // Structure may be a side-effecting expression (e.g. function call).
- auto* sem_structure = Sem(expr->structure);
- bool has_side_effects = sem_structure && sem_structure->HasSideEffects();
-
return builder_->create<sem::StructMemberAccess>(
expr, ret, current_statement_, member, has_side_effects);
}
@@ -1819,7 +1819,7 @@
static_cast<uint32_t>(size));
}
return builder_->create<sem::Swizzle>(expr, ret, current_statement_,
- std::move(swizzle));
+ std::move(swizzle), has_side_effects);
}
AddError(
diff --git a/src/tint/resolver/side_effects_test.cc b/src/tint/resolver/side_effects_test.cc
index 944ff5d..50f4e99 100644
--- a/src/tint/resolver/side_effects_test.cc
+++ b/src/tint/resolver/side_effects_test.cc
@@ -217,7 +217,7 @@
EXPECT_FALSE(sem->HasSideEffects());
}
-TEST_F(SideEffectsTest, MemberAccessor_VectorSwizzle) {
+TEST_F(SideEffectsTest, MemberAccessor_VectorSwizzleNoSE) {
auto* var = Decl(Var("a", ty.vec4<f32>()));
auto* expr = MemberAccessor("a", "xzyw");
WrapInFunction(var, expr);
@@ -229,6 +229,18 @@
EXPECT_FALSE(sem->HasSideEffects());
}
+TEST_F(SideEffectsTest, MemberAccessor_VectorSwizzleSE) {
+ MakeSideEffectFunc("se", [&] { return ty.vec4<f32>(); });
+ auto* expr = MemberAccessor(Call("se"), "xzyw");
+ WrapInFunction(expr);
+
+ EXPECT_TRUE(r()->Resolve()) << r()->error();
+ auto* sem = Sem().Get(expr);
+ EXPECT_TRUE(sem->Is<sem::Swizzle>());
+ ASSERT_NE(sem, nullptr);
+ EXPECT_TRUE(sem->HasSideEffects());
+}
+
TEST_F(SideEffectsTest, Binary_NoSE) {
auto* a = Decl(Var("a", ty.i32()));
auto* b = Decl(Var("b", ty.i32()));
diff --git a/src/tint/sem/member_accessor_expression.cc b/src/tint/sem/member_accessor_expression.cc
index 26f3842..53b1402 100644
--- a/src/tint/sem/member_accessor_expression.cc
+++ b/src/tint/sem/member_accessor_expression.cc
@@ -46,8 +46,9 @@
Swizzle::Swizzle(const ast::MemberAccessorExpression* declaration,
const sem::Type* type,
const Statement* statement,
- std::vector<uint32_t> indices)
- : Base(declaration, type, statement, /* has_side_effects */ false),
+ std::vector<uint32_t> indices,
+ bool has_side_effects)
+ : Base(declaration, type, statement, has_side_effects),
indices_(std::move(indices)) {}
Swizzle::~Swizzle() = default;
diff --git a/src/tint/sem/member_accessor_expression.h b/src/tint/sem/member_accessor_expression.h
index df49504..9eed53b 100644
--- a/src/tint/sem/member_accessor_expression.h
+++ b/src/tint/sem/member_accessor_expression.h
@@ -88,10 +88,12 @@
/// @param type the resolved type of the expression
/// @param statement the statement that owns this expression
/// @param indices the swizzle indices
+ /// @param has_side_effects whether this expression may have side effects
Swizzle(const ast::MemberAccessorExpression* declaration,
const sem::Type* type,
const Statement* statement,
- std::vector<uint32_t> indices);
+ std::vector<uint32_t> indices,
+ bool has_side_effects);
/// Destructor
~Swizzle() override;