From 6c2adf84ed4c5e2efb9e1f742bf797ac99cd88aa Mon Sep 17 00:00:00 2001 From: Minseong Jang Date: Fri, 25 Mar 2022 11:46:26 +0900 Subject: [PATCH] Restrict global variable initializer form --- src/c/parse.rs | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/c/parse.rs b/src/c/parse.rs index be67b7d..9a9115e 100644 --- a/src/c/parse.rs +++ b/src/c/parse.rs @@ -74,7 +74,10 @@ impl AssertSupported for TranslationUnit { impl AssertSupported for ExternalDeclaration { fn assert_supported(&self) { match self { - Self::Declaration(decl) => decl.assert_supported(), + Self::Declaration(decl) => { + assert!(is_valid_global_variable_declaration(&decl.node)); + decl.assert_supported() + } Self::StaticAssert(_) => panic!("ExternalDeclaration::StaticAssert"), Self::FunctionDefinition(fdef) => fdef.assert_supported(), } @@ -609,3 +612,35 @@ impl AssertSupported for AlignOf { self.0.assert_supported(); } } + +#[inline] +pub fn is_valid_global_variable_declaration(decl: &Declaration) -> bool { + let declarators = &decl.declarators; + + declarators.iter().all(|init_decl| { + if let Some(initializer) = &init_decl.node.initializer { + is_valid_global_variable_initializer(&initializer.node) + } else { + true + } + }) +} + +#[inline] +pub fn is_valid_global_variable_initializer(initializer: &Initializer) -> bool { + match initializer { + Initializer::Expression(expr) => match &expr.node { + Expression::Constant(_) => true, + Expression::UnaryOperator(unary) => { + matches!( + &unary.node.operator.node, + UnaryOperator::Minus | UnaryOperator::Plus + ) && matches!(&unary.node.operand.node, Expression::Constant(_)) + } + _ => false, + }, + Initializer::List(items) => items + .iter() + .all(|item| is_valid_global_variable_initializer(&item.node.initializer.node)), + } +}