use crate::memory_model::MemoryOrdering;
use crate::validate::{err, ValidationError};
#[inline]
pub(crate) fn check_barrier(
divergent: bool,
ordering: MemoryOrdering,
errors: &mut Vec<ValidationError>,
) {
if divergent {
errors.push(err(
"V010: barrier may be reached by only part of a workgroup. Fix: move the barrier to uniform control flow."
.to_string(),
));
}
if !ordering.is_valid_for_barrier() {
errors.push(err(format!(
"V043: barrier uses memory ordering `{ordering:?}`, but barriers must synchronize memory. Fix: use Acquire, Release, AcqRel, or SeqCst; use no barrier at all for Relaxed."
)));
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn divergent_barrier_emits_v010() {
let mut errors = Vec::new();
check_barrier(true, MemoryOrdering::SeqCst, &mut errors);
assert_eq!(errors.len(), 1);
assert!(errors[0].message().contains("V010"));
}
#[test]
fn uniform_barrier_is_valid() {
let mut errors = Vec::new();
check_barrier(false, MemoryOrdering::SeqCst, &mut errors);
assert!(errors.is_empty());
}
#[test]
fn relaxed_barrier_is_rejected() {
let mut errors = Vec::new();
check_barrier(false, MemoryOrdering::Relaxed, &mut errors);
assert!(errors.iter().any(|error| error.message().contains("V043")));
}
}