From f81c1081ea7d27ea55f373c0bfaf651e491da7e6 Mon Sep 17 00:00:00 2001 From: David Neto Date: Fri, 23 Oct 2020 23:39:25 +0000 Subject: [PATCH] wgsl-reader: treat function formal params as const They should only be singly-assigned. This is required because consts can hold pointers, but var's cannot. And we need to support pointer arguments. Bug: tint:275 Change-Id: I00a58734725bd08d40df71c736854a93c364a33c Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/30923 Reviewed-by: dan sinclair Commit-Queue: dan sinclair --- src/reader/wgsl/parser_impl.cc | 10 ++++++++-- src/reader/wgsl/parser_impl_param_list_test.cc | 4 ++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc index 33a487fdf8..09f5348e26 100644 --- a/src/reader/wgsl/parser_impl.cc +++ b/src/reader/wgsl/parser_impl.cc @@ -1991,8 +1991,14 @@ ast::VariableList ParserImpl::param_list() { return {}; for (;;) { - ret.push_back(std::make_unique( - source, name, ast::StorageClass::kNone, type)); + auto var = std::make_unique(source, name, + ast::StorageClass::kNone, type); + // Formal parameters are treated like a const declaration where the + // initializer value is provided by the call's argument. The key point is + // that it's not updatable after intially set. This is unlike C or GLSL + // which treat formal parameters like local variables that can be updated. + var->set_is_const(true); + ret.push_back(std::move(var)); t = peek(); if (!t.IsComma()) diff --git a/src/reader/wgsl/parser_impl_param_list_test.cc b/src/reader/wgsl/parser_impl_param_list_test.cc index ca8c38e212..1d0b12a635 100644 --- a/src/reader/wgsl/parser_impl_param_list_test.cc +++ b/src/reader/wgsl/parser_impl_param_list_test.cc @@ -38,6 +38,7 @@ TEST_F(ParserImplTest, ParamList_Single) { EXPECT_EQ(e[0]->name(), "a"); EXPECT_EQ(e[0]->type(), i32); + EXPECT_TRUE(e[0]->is_const()); } TEST_F(ParserImplTest, ParamList_Multiple) { @@ -52,12 +53,15 @@ TEST_F(ParserImplTest, ParamList_Multiple) { EXPECT_EQ(e[0]->name(), "a"); EXPECT_EQ(e[0]->type(), i32); + EXPECT_TRUE(e[0]->is_const()); EXPECT_EQ(e[1]->name(), "b"); EXPECT_EQ(e[1]->type(), f32); + EXPECT_TRUE(e[1]->is_const()); EXPECT_EQ(e[2]->name(), "c"); EXPECT_EQ(e[2]->type(), vec2); + EXPECT_TRUE(e[1]->is_const()); } TEST_F(ParserImplTest, ParamList_Empty) {