aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2018-12-05 18:40:01 +0100
committerTristan Gingold <tgingold@free.fr>2018-12-05 18:40:01 +0100
commit837eab3fa61abef9ce12aa66a2b12009970f18dc (patch)
tree29def993fd1032d9f2dd64f0c340449b9a5f56f0
parent4128f21b2099ee0f15aa9f32bb5ea0c1e98b6dc5 (diff)
downloadghdl-837eab3fa61abef9ce12aa66a2b12009970f18dc.tar.gz
ghdl-837eab3fa61abef9ce12aa66a2b12009970f18dc.tar.bz2
ghdl-837eab3fa61abef9ce12aa66a2b12009970f18dc.zip
parser: do not try to parse when parenthesis are too nested.
-rw-r--r--src/vhdl/parse.adb54
1 files changed, 53 insertions, 1 deletions
diff --git a/src/vhdl/parse.adb b/src/vhdl/parse.adb
index b72aa5a89..58c3833af 100644
--- a/src/vhdl/parse.adb
+++ b/src/vhdl/parse.adb
@@ -71,6 +71,12 @@ package body Parse is
function Parse_Tolerance_Aspect_Opt return Iir;
function Parse_Package (Parent : Iir) return Iir;
+ -- Maximum number of nested parenthesis, before generating an error.
+ Max_Parenthesis_Depth : constant Natural := 1000;
+
+ -- Current number of open parenthesis (in expressions).
+ Parenthesis_Depth : Natural := 0;
+
-- Copy the current location into an iir.
procedure Set_Location (Node : Iir) is
begin
@@ -5212,6 +5218,41 @@ package body Parse is
return Res;
end Parse_Integer_Literal;
+ procedure Skip_Until_Closing_Parenthesis
+ is
+ Level : Natural;
+ begin
+ Level := 0;
+
+ -- Skip '('.
+ Scan;
+
+ loop
+ case Current_Token is
+ when Tok_Right_Paren =>
+ if Level = 0 then
+ -- Skip ')'.
+ Scan;
+ exit;
+ end if;
+ Level := Level - 1;
+ when Tok_Left_Paren =>
+ Level := Level + 1;
+ when Tok_Eof
+ | Tok_Semi_Colon
+ | Tok_End
+ | Tok_Then
+ | Tok_Else
+ | Tok_Loop =>
+ exit;
+ when others =>
+ null;
+ end case;
+
+ Scan;
+ end loop;
+ end Skip_Until_Closing_Parenthesis;
+
-- precond : next token
-- postcond: next token
--
@@ -5303,7 +5344,17 @@ package body Parse is
end if;
return Res;
when Tok_Left_Paren =>
- return Parse_Aggregate;
+ if Parenthesis_Depth = Max_Parenthesis_Depth then
+ Error_Msg_Parse
+ ("too many open parenthesis, skip to the matching one");
+ Skip_Until_Closing_Parenthesis;
+ return Null_Iir;
+ else
+ Parenthesis_Depth := Parenthesis_Depth + 1;
+ Res := Parse_Aggregate;
+ Parenthesis_Depth := Parenthesis_Depth - 1;
+ return Res;
+ end if;
when Tok_String =>
return Parse_Name;
when Tok_Null =>
@@ -9506,6 +9557,7 @@ package body Parse is
begin
-- Internal check: there must be no current_token.
pragma Assert (Current_Token = Tok_Invalid);
+ pragma Assert (Parenthesis_Depth = 0);
-- Read the first token.
Scan;