Skip to content

Result expressions aren't validated to actually be populated by their corresponding statement types #5740

@jimblandy

Description

@jimblandy

The Naga validator fails to ensure that CallResult and AtomicResult expressions indeed have their values provided by Call and Atomic statements. The following test passes, but I think it should fail:

use naga::{valid, Expression, Scalar, Function};

#[test]
fn emit_atomic_result() {
    use naga::{Module, Type, TypeInner};

    let span = naga::Span::default();
    let mut module = Module::default();
    let ty_u32 = module.types.insert(
        Type {
            name: Some("u32".into()),
            inner: TypeInner::Scalar(Scalar::U32),
        },
        span,
    );

    let mut fun = Function::default();
    let ex_result = fun.expressions.append(
        Expression::AtomicResult {
            ty: ty_u32,
            comparison: false,
        },
        span,
    );

    fun.body.push(
        naga::Statement::Emit(naga::Range::new_from_bounds(ex_result, ex_result)),
        span);

    module.functions.append(fun, span);

    valid::Validator::new(
        valid::ValidationFlags::default(),
        valid::Capabilities::all(),
    )
    .validate(&module)
    .expect("module should validate");
}

#[test]
fn emit_call_result() {
    use naga::{Module, Type, TypeInner};

    let span = naga::Span::default();
    let mut module = Module::default();
    let ty_u32 = module.types.insert(
        Type {
            name: Some("u32".into()),
            inner: TypeInner::Scalar(Scalar::U32),
        },
        span,
    );

    let mut fun_callee = Function {
        result: Some(naga::FunctionResult {
            ty: ty_u32,
            binding: None,
        }),
        .. Function::default()
    };
    let ex_42 = fun_callee.expressions.append(
        Expression::Literal(naga::Literal::U32(42)),
        span,
    );
    fun_callee.body.push(
        naga::Statement::Return { value: Some(ex_42) },
        span
    );
    let fun_u32 = module.functions.append(fun_callee, span);
    
    let mut fun_caller = Function::default();
    let ex_result = fun_caller.expressions.append(
        Expression::CallResult(fun_u32),
        span,
    );

    fun_caller.body.push(
        naga::Statement::Emit(naga::Range::new_from_bounds(ex_result, ex_result)),
        span);

    module.functions.append(fun_caller, span);

    valid::Validator::new(
        valid::ValidationFlags::default(),
        valid::Capabilities::all(),
    )
    .validate(&module)
    .expect("module should validate");
}

The other MumbleResult expressions should be checked as well.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: naga processingPasses over IR in the middlearea: validationIssues related to validation, diagnostics, and error handlingnagaShader Translator

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions