aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2019-02-08 17:28:04 +0200
committerSergey Poznyakoff <gray@gnu.org>2019-02-08 17:28:04 +0200
commitb64ca53d3f65ea7d51afa977e9d4bed808f494f7 (patch)
treeec7e7d1b184c25b716a4a49844fad3cf41cc36e7
parentb0cc5efa1a1c8145981846cfa8e80cc67d12ebf6 (diff)
downloadcflow-b64ca53d3f65ea7d51afa977e9d4bed808f494f7.tar.gz
cflow-b64ca53d3f65ea7d51afa977e9d4bed808f494f7.tar.bz2
Fix https://savannah.gnu.org/bugs/index.php?47110
* src/parser.c (expression): Fix parsing of type casts. * tests/memberof.at: New test case. * tests/testsuite.at: Add new test. * tests/Makefile.am: Add new test.
-rw-r--r--src/parser.c17
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/memberof.at62
-rw-r--r--tests/testsuite.at1
4 files changed, 78 insertions, 3 deletions
diff --git a/src/parser.c b/src/parser.c
index 2b173c2..391fe33 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -602,32 +602,43 @@ expression()
nexttoken();
if (tok.type == '(') {
call(name, line);
parens_lev++;
} else {
reference(name, line);
+
+ /* MEMBER_OF can be preceded by a closing paren, as in
+ (*a)->b
+ */
+ while (parens_lev > 0 && tok.type == ')') {
+ parens_lev--;
+ nexttoken();
+ }
+
if (tok.type == MEMBER_OF) {
- while (tok.type == MEMBER_OF)
- nexttoken();
+ nexttoken();
} else {
putback();
}
}
break;
case '(':
/* maybe typecast */
- if (nexttoken() == TYPE)
+ if (nexttoken() == TYPE || tok.type == STRUCT)
skip_to(')');
else {
putback();
parens_lev++;
}
break;
case ')':
parens_lev--;
break;
+ case MEMBER_OF:
+ nexttoken();
+ break;
}
nexttoken();
}
}
void
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 0beb3b3..d78b7c5 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -47,12 +47,13 @@ TESTSUITE_AT = \
fdecl.at\
funcarg.at\
hiding.at\
include.at\
invalid.at\
knr.at\
+ memberof.at\
multi.at\
nfarg.at\
nfparg.at\
parm.at\
pwrapper.at\
recurse.at\
diff --git a/tests/memberof.at b/tests/memberof.at
new file mode 100644
index 0000000..42e9ec6
--- /dev/null
+++ b/tests/memberof.at
@@ -0,0 +1,62 @@
+# This file is part of GNU cflow testsuite. -*- Autotest -*-
+# Copyright (C) 2016-2019 Sergey Poznyakoff
+#
+# 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, 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 <http://www.gnu.org/licenses/>.
+
+AT_SETUP([member of])
+AT_KEYWORDS([memberof])
+
+CFLOW_CHECK(
+[int bar(struct foo *a) {
+ return a.bar();
+}
+],
+[bar() <int bar (struct foo *a) at prog:1>
+])
+
+# https://savannah.gnu.org/bugs/index.php?47110
+CFLOW_CHECK(
+[int bar(struct foo *a) {
+ return (*a).bar();
+}
+],
+[bar() <int bar (struct foo *a) at prog:1>
+])
+
+CFLOW_CHECK(
+[int bar(struct foo **a) {
+ return (*a)->bar();
+}
+],
+[bar() <int bar (struct foo **a) at prog:1>
+])
+
+CFLOW_CHECK(
+[int bar(void *a) {
+ return (*(struct foo*)a).bar();
+}
+],
+[bar() <int bar (void *a) at prog:1>
+])
+
+CFLOW_CHECK(
+[int bar(void *a) {
+ return (*(struct foo*)(((struct qux*)a)->foo)).bar();
+}
+],
+[bar() <int bar (void *a) at prog:1>
+])
+
+AT_CLEANUP
+
diff --git a/tests/testsuite.at b/tests/testsuite.at
index 766e018..baf997b 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -69,8 +69,9 @@ m4_include([struct00.at])
m4_include([struct01.at])
m4_include([struct02.at])
m4_include([struct03.at])
m4_include([struct04.at])
m4_include([decl01.at])
m4_include([invalid.at])
+m4_include([memberof.at])
# End of testsuite.at

Return to:

Send suggestions and report system problems to the System administrator.