]> git.draconx.ca Git - cdecl99.git/commitdiff
Fix parsing of int (x*).
authorNick Bowler <nbowler@draconx.ca>
Thu, 2 Jul 2020 22:45:15 +0000 (18:45 -0400)
committerNick Bowler <nbowler@draconx.ca>
Fri, 3 Jul 2020 03:19:15 +0000 (23:19 -0400)
We are incorrectly eliminating the function declarator from this
parse, which ends up "flipping" the pointer declarator.  So the
result is simply wrong.  Fix that up.

Also remove some contextless notes in a comment which I am no
longer smart enough to understand.

src/parse-decl.c
tests/decl-good.at [new file with mode: 0644]
testsuite.at

index 4489532cdaa1f232862968c47871dafe53431f65..e96efb7073362ba47eda7e8c6341362cc1246980 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Parse and validate C declarations.
- *  Copyright © 2011-2012 Nick Bowler
+ *  Copyright © 2011-2012, 2020 Nick Bowler
  *
  *  This program is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -116,12 +116,6 @@ static bool valid_declspecs(struct cdecl *decl, bool top)
  * if a declarator could be interpreted as something other than a function,
  * do that.
  *
- *   - The function declarator has a null child declarator.
- *   - The function declarator has exactly one parameter, and is not variadic.
- *   - The function parameter has a type specifier, and it is a typedef name.
- *   - The function parameter has no other declaration specifiers.
- *   - The function parameter does not declare an identifier.
- *
  * Since cdecl99 supports things like [*] in any context (in C, such constructs
  * are only valid in function parameter lists), we don't treat them specially
  * here.
@@ -165,6 +159,8 @@ static bool function_is_reducible(struct cdecl_declarator *d)
                return false; /* e.g. int (int) */
        if (d->u.function.parameters->specifiers->next)
                return false; /* e.g. int (size_t const) */
+       if (d->u.function.parameters->declarators->type == CDECL_DECL_POINTER)
+               return false; /* e.g. int (x *) */
 
        return true;
 }
diff --git a/tests/decl-good.at b/tests/decl-good.at
new file mode 100644 (file)
index 0000000..5b8b9a6
--- /dev/null
@@ -0,0 +1,27 @@
+# Copyright © 2020 Nick Bowler
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+AT_BANNER([C declarations])
+
+m4_define([CHECK_DECL],
+[AT_DATA([expout], [[$2]m4_newline])
+AT_CHECK([cdecl99 -e 'explain $1'], [0], [expout])])
+
+m4_define([SIMPLE_DECL],
+[AT_SETUP([$1])
+CHECK_DECL([$1], [$2])
+AT_CLEANUP])
+
+SIMPLE_DECL([int (x*)], [type function (pointer to x) returning int])
index 0f27c56e62b0ba38323b0e52ba79bf9a9c1f6086..dc1678319484636689074175b3b7146ebd9eccb3 100644 (file)
@@ -23,4 +23,5 @@ m4_divert_push([PREPARE_TESTS])dnl
 m4_divert_pop([PREPARE_TESTS])
 
 m4_include([tests/general.at])
+m4_include([tests/decl-good.at])
 m4_include([tests/decl-bad.at])