aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-02-07 14:50:00 +0900
committernsfisis <nsfisis@gmail.com>2026-02-07 15:19:14 +0900
commit4fc8caf7db28d89d7f347004663ed2634f8f1bd7 (patch)
tree2dbe11fda97d5d86fb6fa63de2ccdb491629a7c5
parentb8780671f6768e3b5a09084d9f80c01bd544d2e8 (diff)
downloadducc-4fc8caf7db28d89d7f347004663ed2634f8f1bd7.tar.gz
ducc-4fc8caf7db28d89d7f347004663ed2634f8f1bd7.tar.zst
ducc-4fc8caf7db28d89d7f347004663ed2634f8f1bd7.zip
fix: function-like macro name not followed by parenthesis
-rw-r--r--src/preprocess.c8
-rw-r--r--tests/macros.sh24
2 files changed, 31 insertions, 1 deletions
diff --git a/src/preprocess.c b/src/preprocess.c
index b826bf2..b23ec4e 100644
--- a/src/preprocess.c
+++ b/src/preprocess.c
@@ -541,7 +541,9 @@ static MacroArgArray* pp_parse_macro_arguments(Preprocessor* pp, bool skip_newli
MacroArgArray* args = macroargs_new();
skip_whitespaces_or_newlines(pp, skip_newline);
- expect_pp_token(pp, TokenKind_paren_l);
+ if (!consume_pp_token_if(pp, TokenKind_paren_l)) {
+ return NULL;
+ }
skip_whitespaces_or_newlines(pp, skip_newline);
Token* tok = peek_pp_token(pp);
if (!skip_newline && tok->kind == TokenKind_newline) {
@@ -735,6 +737,10 @@ static int expand_macro(Preprocessor* pp, bool skip_newline, MacroExpansionConte
if (macro->kind == MacroKind_func) {
next_pp_token(pp);
MacroArgArray* args = pp_parse_macro_arguments(pp, skip_newline);
+ if (!args) {
+ // If function-like macro name is not followed by opening parenthesis, it is not a macro invocation.
+ return pp->pos - macro_name_pos;
+ }
token_count_before_expansion = pp->pos - macro_name_pos;
replace_pp_tokens(pp, macro_name_pos, pp->pos, &macro->replacements);
diff --git a/tests/macros.sh b/tests/macros.sh
index 902f168..a6cf3df 100644
--- a/tests/macros.sh
+++ b/tests/macros.sh
@@ -422,3 +422,27 @@ int main() {
#endif
}
EOF
+
+cat <<'EOF' > expected
+42
+EOF
+test_diff <<'EOF'
+int printf();
+
+#define m1(x) x
+
+int main() {
+ int m1 = 42;
+ printf("%d\n", m1);
+}
+EOF
+
+cat <<'EOF' > expected
+struct { int foo; } s;
+int x = ( ( 1) * 2);
+EOF
+test_cpp <<'EOF'
+#define foo(x) ((x) * 2)
+struct { int foo; } s;
+int x = foo(1);
+EOF