Skip to content

Commit ff3b1ff

Browse files
committed
[cc] unterminated macro updates
Added EOF/unterminated macro detection to collect_macro_args in cc/token/preprocess.rs: 1. Extended function signature to take macro_pos: &Position and macro_name: &str for error reporting 2. Added tracking variable found_closing_paren to detect if we exited normally vs ran out of tokens 3. Added error reporting when the loop exits without finding the closing ): if !found_closing_paren { crate::diag::error( *macro_pos, &format!( "unterminated argument list invoking macro \"{}\"", macro_name ), ); } 4. Updated all 4 call sites to pass the position and macro name This now matches sparse's behavior - reporting "unterminated argument list invoking macro X" when EOF is reached before finding the closing ), while correctly allowing multiline macro calls (no newline-based breaking).
1 parent e743ea1 commit ff3b1ff

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

cc/token/preprocess.rs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,12 @@ impl<'a> Preprocessor<'a> {
679679
// Pop the identifier and expand as function-like macro
680680
let last_token = output.pop().unwrap();
681681
iter.next(); // consume '('
682-
let args = self.collect_macro_args(&mut iter, idents);
682+
let args = self.collect_macro_args(
683+
&mut iter,
684+
idents,
685+
&last_token.pos,
686+
&macro_name,
687+
);
683688
let mac = mac.clone();
684689
if let Some(more_expanded) = self.expand_function_macro(
685690
&mac,
@@ -1715,7 +1720,7 @@ impl<'a> Preprocessor<'a> {
17151720
if let TokenValue::Special(code) = &next.value {
17161721
if *code == b'(' as u32 {
17171722
iter.next(); // consume '('
1718-
let args = self.collect_macro_args(iter, idents);
1723+
let args = self.collect_macro_args(iter, idents, pos, name);
17191724
return self.expand_function_macro(&mac, &args, pos, idents);
17201725
}
17211726
}
@@ -1733,6 +1738,8 @@ impl<'a> Preprocessor<'a> {
17331738
&self,
17341739
iter: &mut std::iter::Peekable<I>,
17351740
_idents: &IdentTable,
1741+
macro_pos: &Position,
1742+
macro_name: &str,
17361743
) -> Vec<Vec<Token>>
17371744
where
17381745
I: Iterator<Item = Token>,
@@ -1742,6 +1749,7 @@ impl<'a> Preprocessor<'a> {
17421749
// Start at depth 1 because the opening '(' has already been consumed
17431750
// by the caller. This is important for handling multiline macro calls.
17441751
let mut paren_depth = 1;
1752+
let mut found_closing_paren = false;
17451753

17461754
for token in iter.by_ref() {
17471755
match &token.value {
@@ -1756,6 +1764,7 @@ impl<'a> Preprocessor<'a> {
17561764
if !current_arg.is_empty() || !args.is_empty() {
17571765
args.push(current_arg);
17581766
}
1767+
found_closing_paren = true;
17591768
break;
17601769
}
17611770
// Nested ')' - add to current argument
@@ -1774,6 +1783,17 @@ impl<'a> Preprocessor<'a> {
17741783
}
17751784
}
17761785

1786+
// Check for unterminated macro call (EOF before closing ')')
1787+
if !found_closing_paren {
1788+
crate::diag::error(
1789+
*macro_pos,
1790+
&format!(
1791+
"unterminated argument list invoking macro \"{}\"",
1792+
macro_name
1793+
),
1794+
);
1795+
}
1796+
17771797
args
17781798
}
17791799

@@ -2049,7 +2069,7 @@ impl<'a> Preprocessor<'a> {
20492069
&mut self,
20502070
builtin: BuiltinMacro,
20512071
pos: &Position,
2052-
_mac: &Macro,
2072+
mac: &Macro,
20532073
iter: &mut std::iter::Peekable<I>,
20542074
idents: &mut IdentTable,
20552075
) -> Option<Vec<Token>>
@@ -2105,7 +2125,7 @@ impl<'a> Preprocessor<'a> {
21052125
if let TokenValue::Special(code) = &next.value {
21062126
if *code == b'(' as u32 {
21072127
iter.next();
2108-
let args = self.collect_macro_args(iter, idents);
2128+
let args = self.collect_macro_args(iter, idents, pos, &mac.name);
21092129
let result = self.eval_has_builtin(builtin, &args, idents);
21102130
return Some(vec![Token::with_value(
21112131
TokenType::Number,
@@ -2127,7 +2147,7 @@ impl<'a> Preprocessor<'a> {
21272147
if let TokenValue::Special(code) = &next.value {
21282148
if *code == b'(' as u32 {
21292149
iter.next();
2130-
let args = self.collect_macro_args(iter, idents);
2150+
let args = self.collect_macro_args(iter, idents, pos, &mac.name);
21312151
let result = self.eval_has_include(&args, idents);
21322152
return Some(vec![Token::with_value(
21332153
TokenType::Number,

0 commit comments

Comments
 (0)