aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2021-04-04 14:01:12 +0300
committerSergey Poznyakoff <gray@gnu.org>2021-04-04 14:56:04 +0300
commit52b63882560c34afaf0575233cbb815b0de5d87d (patch)
tree730e86e78124c74d286e7227f72e830fde44f834 /src
parent1ba2daa59361c916ad0a39d33bfc54899d8613a3 (diff)
downloadcflow-52b63882560c34afaf0575233cbb815b0de5d87d.tar.gz
cflow-52b63882560c34afaf0575233cbb815b0de5d87d.tar.bz2
Improve parsing of typecasts.
* src/cflow.rc: Mark 'typeof' as wrapper. * src/parser.c (expression): Allow for wrappers and explicit structures in typecasts. (dcl): Don't skip token that follows the wrapper. * tests/struct.at: Test for unions in typecasts.
Diffstat (limited to 'src')
-rw-r--r--src/c.l4
-rw-r--r--src/cflow.rc3
-rw-r--r--src/parser.c36
3 files changed, 32 insertions, 11 deletions
diff --git a/src/c.l b/src/c.l
index 61d1598..9fdf5ce 100644
--- a/src/c.l
+++ b/src/c.l
@@ -76,9 +76,7 @@ typedef return TYPEDEF;
struct {yylval.str = "struct"; return STRUCT;}
union {yylval.str = "union"; return STRUCT;}
enum {yylval.str = "enum"; return STRUCT;}
-\* { yylval.str = "*";
- return MODIFIER;
- }
+\* {yylval.str = "*"; return MODIFIER;}
/* Operators
*
*/
diff --git a/src/cflow.rc b/src/cflow.rc
index 768fae9..4ce09fd 100644
--- a/src/cflow.rc
+++ b/src/cflow.rc
@@ -5,6 +5,9 @@
--symbol __const:=const
--symbol __restrict:=restrict
--symbol __extension__:qualifier
+--symbol typeof:wrapper
+--symbol __typeof:=typeof
+--symbol __typeof__:=typeof
--symbol __attribute__:wrapper
--symbol __asm__:wrapper
--symbol __nonnull:wrapper
diff --git a/src/parser.c b/src/parser.c
index a3724e0..b71d14d 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -594,6 +594,14 @@ expression()
switch (tok.type) {
case ';':
return;
+ case PARM_WRAPPER:
+ if (skip_balanced('(', ')', 0) == -1) {
+ file_error(_("unexpected end of file in expression"),
+ NULL);
+ return;
+ }
+ putback();
+ break;
case LBRACE:
case LBRACE0:
case RBRACE:
@@ -637,12 +645,23 @@ expression()
break;
case '(':
/* maybe typecast */
- if (nexttoken() == TYPE || tok.type == STRUCT)
- skip_to(')');
- else {
- putback();
+ if (nexttoken() == TYPE || tok.type == STRUCT) {
+ if (skip_balanced('(', ')', 1) == -1) {
+ file_error(_("unexpected end of file in expression"),
+ NULL);
+ return;
+ }
+ if (tok.type == LBRACE || tok.type == LBRACE0) {
+ if (skip_balanced('{', '}', 1) == -1) {
+ file_error(_("unexpected end of file in expression"),
+ NULL);
+ return;
+ }
+ }
+ } else {
parens_lev++;
}
+ putback();
break;
case ')':
parens_lev--;
@@ -895,6 +914,7 @@ dcl(Ident *idptr)
NULL);
return 1;
}
+ putback();
} else if (tok.type == IDENTIFIER) {
int type;
@@ -1066,7 +1086,7 @@ func_body()
parse_declaration(&ident, 0);
break;
case LBRACE0:
- case '{':
+ case LBRACE:
level++;
break;
case RBRACE0:
@@ -1080,7 +1100,7 @@ func_body()
}
/* else: */
/* FALLTHRU */
- case '}':
+ case RBRACE:
delete_autos(level);
level--;
break;
@@ -1088,10 +1108,10 @@ func_body()
if (verbose)
file_error(_("unexpected end of file in function body"),
NULL);
- caller = NULL;
- return;
+ goto end;
}
}
+end:
caller = NULL;
}

Return to:

Send suggestions and report system problems to the System administrator.