tint/resolver: Fix BuiltinCall validator nullptr deref
This patch fix a nullptr dereference case in Validator::BuiltinCall, which check if a no-return-value built-in is called in something other than call statement. Such call may don't have a statement context at all. Bug: chromium:1346830 Change-Id: Ieef02daa5c93a3ac253cd7a7366a53e0fc7887b1 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/96986 Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Zhaoming Jiang <zhaoming.jiang@intel.com> Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
401ac122d5
commit
659d58ceca
|
@ -1602,11 +1602,16 @@ bool Validator::IfStatement(const sem::IfStatement* stmt) const {
|
|||
bool Validator::BuiltinCall(const sem::Call* call) const {
|
||||
if (call->Type()->Is<sem::Void>()) {
|
||||
bool is_call_statement = false;
|
||||
if (auto* call_stmt = As<ast::CallStatement>(call->Stmt()->Declaration())) {
|
||||
if (call_stmt->expr == call->Declaration()) {
|
||||
// Some built-in call are not owned by a statement, e.g. a built-in called in global
|
||||
// variable declaration. Calling no-return-value built-in in these context is invalid as
|
||||
// well.
|
||||
if (auto* call_stmt = call->Stmt()) {
|
||||
if (auto* call_stmt_ast = As<ast::CallStatement>(call_stmt->Declaration())) {
|
||||
if (call_stmt_ast->expr == call->Declaration()) {
|
||||
is_call_statement = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!is_call_statement) {
|
||||
// https://gpuweb.github.io/gpuweb/wgsl/#function-call-expr
|
||||
// If the called function does not return a value, a function call
|
||||
|
|
|
@ -40,6 +40,24 @@ TEST_F(ResolverVariableValidationTest, GlobalVarNoInitializerNoType) {
|
|||
EXPECT_EQ(r()->error(), "12:34 error: var declaration requires a type or initializer");
|
||||
}
|
||||
|
||||
TEST_F(ResolverVariableValidationTest, VarInitializerNoReturnValueBuiltin) {
|
||||
// fn f() { var a = storageBarrier(); }
|
||||
auto* NoReturnValueBuiltin = Call(Source{{12, 34}}, "storageBarrier");
|
||||
WrapInFunction(Var("a", nullptr, ast::StorageClass::kNone, NoReturnValueBuiltin));
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(), "12:34 error: builtin 'storageBarrier' does not return a value");
|
||||
}
|
||||
|
||||
TEST_F(ResolverVariableValidationTest, GlobalVarInitializerNoReturnValueBuiltin) {
|
||||
// var a = storageBarrier();
|
||||
auto* NoReturnValueBuiltin = Call(Source{{12, 34}}, "storageBarrier");
|
||||
GlobalVar("a", nullptr, ast::StorageClass::kNone, NoReturnValueBuiltin);
|
||||
|
||||
EXPECT_FALSE(r()->Resolve());
|
||||
EXPECT_EQ(r()->error(), "12:34 error: builtin 'storageBarrier' does not return a value");
|
||||
}
|
||||
|
||||
TEST_F(ResolverVariableValidationTest, GlobalVarUsedAtModuleScope) {
|
||||
// var<private> a : i32;
|
||||
// var<private> b : i32 = a;
|
||||
|
|
Loading…
Reference in New Issue