From 3adfcc67feb7f075ce17e59eeb415dbe76b84648 Mon Sep 17 00:00:00 2001
From: Andre Maroneze <andre.maroneze@cea.fr>
Date: Tue, 12 Oct 2021 22:15:13 +0200
Subject: [PATCH] [Cabs2cil] avoid stack overflow with large initializer case
 ranges

---
 src/kernel_internals/typing/cabs2cil.ml       |  3 +++
 .../oracle/very_large_integers.0.res.oracle   |  8 +++---
 .../oracle/very_large_integers.1.res.oracle   |  8 +++---
 .../oracle/very_large_integers.10.res.oracle  | 16 +++++-------
 .../oracle/very_large_integers.11.res.oracle  | 15 ++++++-----
 .../oracle/very_large_integers.12.res.oracle  |  9 ++++---
 .../oracle/very_large_integers.13.res.oracle  | 25 ++++++-------------
 .../oracle/very_large_integers.14.res.oracle  | 22 ++++++++++++++++
 .../oracle/very_large_integers.2.res.oracle   |  4 +--
 .../oracle/very_large_integers.3.res.oracle   |  2 +-
 .../oracle/very_large_integers.4.res.oracle   |  2 +-
 .../oracle/very_large_integers.5.res.oracle   | 12 ++++-----
 .../oracle/very_large_integers.6.res.oracle   |  6 ++---
 .../oracle/very_large_integers.7.res.oracle   |  8 +-----
 .../oracle/very_large_integers.8.res.oracle   |  7 +++---
 .../oracle/very_large_integers.9.res.oracle   |  7 +++---
 tests/syntax/very_large_integers.c            |  8 +++++-
 17 files changed, 88 insertions(+), 74 deletions(-)
 create mode 100644 tests/syntax/oracle/very_large_integers.14.res.oracle

diff --git a/src/kernel_internals/typing/cabs2cil.ml b/src/kernel_internals/typing/cabs2cil.ml
index b5b1e8e6c8f..3f31de7afad 100644
--- a/src/kernel_internals/typing/cabs2cil.ml
+++ b/src/kernel_internals/typing/cabs2cil.ml
@@ -8550,6 +8550,9 @@ and doInit local_env asconst add_implicit_ensures preinit so acc initl =
             "start index larger than end index in range initializer";
         let rec loop (i: int) =
           if i > last then restil
+          else
+          if last - i > 100_000 then
+            Kernel.fatal ~current:true "INDEX_RANGE too large"
           else
             (top (Cabs.ATINDEX_INIT(
                  { expr_node = Cabs.CONSTANT(Cabs.CONST_INT(string_of_int i));
diff --git a/tests/syntax/oracle/very_large_integers.0.res.oracle b/tests/syntax/oracle/very_large_integers.0.res.oracle
index 1cba593f0dc..5c399742978 100644
--- a/tests/syntax/oracle/very_large_integers.0.res.oracle
+++ b/tests/syntax/oracle/very_large_integers.0.res.oracle
@@ -1,11 +1,11 @@
 [kernel] Parsing tests/syntax/very_large_integers.c (with preprocessing)
-[kernel] tests/syntax/very_large_integers.c:23: User Error: 
-  integer constant too large in expression (unsigned long long)999999999999999999 + 9999999999999999999
 [kernel] tests/syntax/very_large_integers.c:24: User Error: 
+  integer constant too large in expression (unsigned long long)999999999999999999 + 9999999999999999999
+[kernel] tests/syntax/very_large_integers.c:25: User Error: 
   bitfield width is not a valid integer constant
-[kernel] tests/syntax/very_large_integers.c:67: Warning: 
+[kernel] tests/syntax/very_large_integers.c:73: Warning: 
   ignoring invalid aligned attribute: __aligned__(9223372036854775808)
-[kernel] tests/syntax/very_large_integers.c:67: Warning: 
+[kernel] tests/syntax/very_large_integers.c:73: Warning: 
   ignoring invalid aligned attribute: __aligned__((9223372036854775808)+
                                                    (9223372036854775808) )
 [kernel] User Error: stopping on file "tests/syntax/very_large_integers.c" that has errors. Add
diff --git a/tests/syntax/oracle/very_large_integers.1.res.oracle b/tests/syntax/oracle/very_large_integers.1.res.oracle
index 29f4d99b928..cdb3ec56daf 100644
--- a/tests/syntax/oracle/very_large_integers.1.res.oracle
+++ b/tests/syntax/oracle/very_large_integers.1.res.oracle
@@ -1,11 +1,11 @@
 [kernel] Parsing tests/syntax/very_large_integers.c (with preprocessing)
-[kernel] tests/syntax/very_large_integers.c:30: User Error: 
+[kernel] tests/syntax/very_large_integers.c:31: User Error: 
   Cannot represent the integer 99999999999999999999U
-[kernel] tests/syntax/very_large_integers.c:30: User Error: 
+[kernel] tests/syntax/very_large_integers.c:31: User Error: 
   Cannot represent the integer 99999999999999999999U
-[kernel] tests/syntax/very_large_integers.c:67: Warning: 
+[kernel] tests/syntax/very_large_integers.c:73: Warning: 
   ignoring invalid aligned attribute: __aligned__(9223372036854775808)
-[kernel] tests/syntax/very_large_integers.c:67: Warning: 
+[kernel] tests/syntax/very_large_integers.c:73: Warning: 
   ignoring invalid aligned attribute: __aligned__((9223372036854775808)+
                                                    (9223372036854775808) )
 [kernel] User Error: stopping on file "tests/syntax/very_large_integers.c" that has errors. Add
diff --git a/tests/syntax/oracle/very_large_integers.10.res.oracle b/tests/syntax/oracle/very_large_integers.10.res.oracle
index b9200fafcf7..5ee077c31fa 100644
--- a/tests/syntax/oracle/very_large_integers.10.res.oracle
+++ b/tests/syntax/oracle/very_large_integers.10.res.oracle
@@ -1,15 +1,11 @@
 [kernel] Parsing tests/syntax/very_large_integers.c (with preprocessing)
-[kernel] tests/syntax/very_large_integers.c:67: Warning: 
+[kernel] tests/syntax/very_large_integers.c:73: Warning: 
   ignoring invalid aligned attribute: __aligned__(9223372036854775808)
-[kernel] tests/syntax/very_large_integers.c:67: Warning: 
+[kernel] tests/syntax/very_large_integers.c:73: Warning: 
   ignoring invalid aligned attribute: __aligned__((9223372036854775808)+
                                                    (9223372036854775808) )
-[eva] Analyzing a complete application starting at main
-[eva] Computing initial state
-[eva] Initial state computed
-[eva:initial-state] Values of globals at initialization
-  nondet ∈ [--..--]
-[kernel:annot-error] tests/syntax/very_large_integers.c:86: Warning: 
-  invalid loop unrolling parameter (-9999999999999999999); ignoring
-[kernel] User Error: warning annot-error treated as fatal error.
+[kernel] tests/syntax/very_large_integers.c:86: Failure: 
+  Invalid digit 9 in integer literal '09876543210' in base 8.
+[kernel] User Error: stopping on file "tests/syntax/very_large_integers.c" that has errors. Add
+  '-kernel-msg-key pp' for preprocessing command.
 [kernel] Frama-C aborted: invalid user input.
diff --git a/tests/syntax/oracle/very_large_integers.11.res.oracle b/tests/syntax/oracle/very_large_integers.11.res.oracle
index 650607ffad8..f34db553ef8 100644
--- a/tests/syntax/oracle/very_large_integers.11.res.oracle
+++ b/tests/syntax/oracle/very_large_integers.11.res.oracle
@@ -1,12 +1,15 @@
 [kernel] Parsing tests/syntax/very_large_integers.c (with preprocessing)
-[kernel] tests/syntax/very_large_integers.c:67: Warning: 
+[kernel] tests/syntax/very_large_integers.c:73: Warning: 
   ignoring invalid aligned attribute: __aligned__(9223372036854775808)
-[kernel] tests/syntax/very_large_integers.c:67: Warning: 
+[kernel] tests/syntax/very_large_integers.c:73: Warning: 
   ignoring invalid aligned attribute: __aligned__((9223372036854775808)+
                                                    (9223372036854775808) )
-[kernel:annot-error] tests/syntax/very_large_integers.c:91: Warning: 
-  Invalid slevel directive. Ignoring code annotation
+[eva] Analyzing a complete application starting at main
+[eva] Computing initial state
+[eva] Initial state computed
+[eva:initial-state] Values of globals at initialization
+  nondet ∈ [--..--]
+[kernel:annot-error] tests/syntax/very_large_integers.c:92: Warning: 
+  invalid loop unrolling parameter (-9999999999999999999); ignoring
 [kernel] User Error: warning annot-error treated as fatal error.
-[kernel] User Error: stopping on file "tests/syntax/very_large_integers.c" that has errors. Add
-  '-kernel-msg-key pp' for preprocessing command.
 [kernel] Frama-C aborted: invalid user input.
diff --git a/tests/syntax/oracle/very_large_integers.12.res.oracle b/tests/syntax/oracle/very_large_integers.12.res.oracle
index ba0dd7c26f2..9bb488764f3 100644
--- a/tests/syntax/oracle/very_large_integers.12.res.oracle
+++ b/tests/syntax/oracle/very_large_integers.12.res.oracle
@@ -1,11 +1,12 @@
 [kernel] Parsing tests/syntax/very_large_integers.c (with preprocessing)
-[kernel] tests/syntax/very_large_integers.c:67: Warning: 
+[kernel] tests/syntax/very_large_integers.c:73: Warning: 
   ignoring invalid aligned attribute: __aligned__(9223372036854775808)
-[kernel] tests/syntax/very_large_integers.c:67: Warning: 
+[kernel] tests/syntax/very_large_integers.c:73: Warning: 
   ignoring invalid aligned attribute: __aligned__((9223372036854775808)+
                                                    (9223372036854775808) )
-[kernel] tests/syntax/very_large_integers.c:95: User Error: 
-  Invalid digit 9 in integer literal '09' in base 8.
+[kernel:annot-error] tests/syntax/very_large_integers.c:97: Warning: 
+  Invalid slevel directive. Ignoring code annotation
+[kernel] User Error: warning annot-error treated as fatal error.
 [kernel] User Error: stopping on file "tests/syntax/very_large_integers.c" that has errors. Add
   '-kernel-msg-key pp' for preprocessing command.
 [kernel] Frama-C aborted: invalid user input.
diff --git a/tests/syntax/oracle/very_large_integers.13.res.oracle b/tests/syntax/oracle/very_large_integers.13.res.oracle
index 29b15f32902..9584d2c1857 100644
--- a/tests/syntax/oracle/very_large_integers.13.res.oracle
+++ b/tests/syntax/oracle/very_large_integers.13.res.oracle
@@ -1,22 +1,11 @@
 [kernel] Parsing tests/syntax/very_large_integers.c (with preprocessing)
-[kernel] tests/syntax/very_large_integers.c:67: Warning: 
+[kernel] tests/syntax/very_large_integers.c:73: Warning: 
   ignoring invalid aligned attribute: __aligned__(9223372036854775808)
-[kernel] tests/syntax/very_large_integers.c:67: Warning: 
+[kernel] tests/syntax/very_large_integers.c:73: Warning: 
   ignoring invalid aligned attribute: __aligned__((9223372036854775808)+
                                                    (9223372036854775808) )
-[kernel] tests/syntax/very_large_integers.c:100: Warning: 
-  ignoring unrolling directive (not an understood constant expression)
-/* Generated by Frama-C */
-int volatile nondet;
-/*@ logic ℤ too_large_integer= 9999999999999999999;
- */
-int main(void)
-{
-  int __retres;
-  /*@ loop pragma UNROLL 99999999999999999999; */
-  while (nondet) ;
-  __retres = 0;
-  return __retres;
-}
-
-
+[kernel] tests/syntax/very_large_integers.c:101: User Error: 
+  Invalid digit 9 in integer literal '09' in base 8.
+[kernel] User Error: stopping on file "tests/syntax/very_large_integers.c" that has errors. Add
+  '-kernel-msg-key pp' for preprocessing command.
+[kernel] Frama-C aborted: invalid user input.
diff --git a/tests/syntax/oracle/very_large_integers.14.res.oracle b/tests/syntax/oracle/very_large_integers.14.res.oracle
new file mode 100644
index 00000000000..829956ff3f3
--- /dev/null
+++ b/tests/syntax/oracle/very_large_integers.14.res.oracle
@@ -0,0 +1,22 @@
+[kernel] Parsing tests/syntax/very_large_integers.c (with preprocessing)
+[kernel] tests/syntax/very_large_integers.c:73: Warning: 
+  ignoring invalid aligned attribute: __aligned__(9223372036854775808)
+[kernel] tests/syntax/very_large_integers.c:73: Warning: 
+  ignoring invalid aligned attribute: __aligned__((9223372036854775808)+
+                                                   (9223372036854775808) )
+[kernel] tests/syntax/very_large_integers.c:106: Warning: 
+  ignoring unrolling directive (not an understood constant expression)
+/* Generated by Frama-C */
+int volatile nondet;
+/*@ logic ℤ too_large_integer= 9999999999999999999;
+ */
+int main(void)
+{
+  int __retres;
+  /*@ loop pragma UNROLL 99999999999999999999; */
+  while (nondet) ;
+  __retres = 0;
+  return __retres;
+}
+
+
diff --git a/tests/syntax/oracle/very_large_integers.2.res.oracle b/tests/syntax/oracle/very_large_integers.2.res.oracle
index 25740fed33d..c4ae365bcb8 100644
--- a/tests/syntax/oracle/very_large_integers.2.res.oracle
+++ b/tests/syntax/oracle/very_large_integers.2.res.oracle
@@ -1,7 +1,7 @@
 [kernel] Parsing tests/syntax/very_large_integers.c (with preprocessing)
-[kernel] tests/syntax/very_large_integers.c:37: User Error: 
+[kernel] tests/syntax/very_large_integers.c:38: User Error: 
   integer constant too large in expression 9999999999999999999U
-[kernel] tests/syntax/very_large_integers.c:37: Failure: 
+[kernel] tests/syntax/very_large_integers.c:38: Failure: 
   Cannot understand the constants in case range
 [kernel] User Error: stopping on file "tests/syntax/very_large_integers.c" that has errors. Add
   '-kernel-msg-key pp' for preprocessing command.
diff --git a/tests/syntax/oracle/very_large_integers.3.res.oracle b/tests/syntax/oracle/very_large_integers.3.res.oracle
index f4cbe4f4e6d..d98169ad396 100644
--- a/tests/syntax/oracle/very_large_integers.3.res.oracle
+++ b/tests/syntax/oracle/very_large_integers.3.res.oracle
@@ -1,5 +1,5 @@
 [kernel] Parsing tests/syntax/very_large_integers.c (with preprocessing)
-[kernel] tests/syntax/very_large_integers.c:45: Failure: Case range too large
+[kernel] tests/syntax/very_large_integers.c:46: Failure: Case range too large
 [kernel] User Error: stopping on file "tests/syntax/very_large_integers.c" that has errors. Add
   '-kernel-msg-key pp' for preprocessing command.
 [kernel] Frama-C aborted: invalid user input.
diff --git a/tests/syntax/oracle/very_large_integers.4.res.oracle b/tests/syntax/oracle/very_large_integers.4.res.oracle
index e53651c2f5b..cb6369a167f 100644
--- a/tests/syntax/oracle/very_large_integers.4.res.oracle
+++ b/tests/syntax/oracle/very_large_integers.4.res.oracle
@@ -1,5 +1,5 @@
 [kernel] Parsing tests/syntax/very_large_integers.c (with preprocessing)
-[kernel] tests/syntax/very_large_integers.c:50: Failure: 
+[kernel] tests/syntax/very_large_integers.c:51: Failure: 
   Array length 9999999999999999999U is not a compile-time constant: no explicit initializer allowed.
 [kernel] User Error: stopping on file "tests/syntax/very_large_integers.c" that has errors. Add
   '-kernel-msg-key pp' for preprocessing command.
diff --git a/tests/syntax/oracle/very_large_integers.5.res.oracle b/tests/syntax/oracle/very_large_integers.5.res.oracle
index 028afa06f27..581438ce1de 100644
--- a/tests/syntax/oracle/very_large_integers.5.res.oracle
+++ b/tests/syntax/oracle/very_large_integers.5.res.oracle
@@ -1,12 +1,12 @@
 [kernel] Parsing tests/syntax/very_large_integers.c (with preprocessing)
-[kernel] tests/syntax/very_large_integers.c:54: User Error: 
+[kernel] tests/syntax/very_large_integers.c:55: User Error: 
   INDEX initialization designator overflows
-  52    
-  53    #ifdef INIT_DESIGNATOR2
-  54    int arr3[1] = { [9999999999999999999U] = 42 };
+  53    
+  54    #ifdef INIT_DESIGNATOR2
+  55    int arr3[1] = { [9999999999999999999U] = 42 };
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-  55    #endif
-  56
+  56    #endif
+  57
 [kernel] User Error: stopping on file "tests/syntax/very_large_integers.c" that has errors. Add
   '-kernel-msg-key pp' for preprocessing command.
 [kernel] Frama-C aborted: invalid user input.
diff --git a/tests/syntax/oracle/very_large_integers.6.res.oracle b/tests/syntax/oracle/very_large_integers.6.res.oracle
index 80ea4f9cf53..c0200e81a9c 100644
--- a/tests/syntax/oracle/very_large_integers.6.res.oracle
+++ b/tests/syntax/oracle/very_large_integers.6.res.oracle
@@ -1,9 +1,9 @@
 [kernel] Parsing tests/syntax/very_large_integers.c (with preprocessing)
-[kernel] tests/syntax/very_large_integers.c:58: User Error: 
+[kernel] tests/syntax/very_large_integers.c:59: User Error: 
   integer constant too large in expression -9999999999999999999U
-[kernel] tests/syntax/very_large_integers.c:58: User Error: 
+[kernel] tests/syntax/very_large_integers.c:59: User Error: 
   integer constant too large in expression 9999999999999999999U
-[kernel] tests/syntax/very_large_integers.c:58: Failure: 
+[kernel] tests/syntax/very_large_integers.c:59: Failure: 
   INDEX_RANGE initialization designator is not a valid constant
 [kernel] User Error: stopping on file "tests/syntax/very_large_integers.c" that has errors. Add
   '-kernel-msg-key pp' for preprocessing command.
diff --git a/tests/syntax/oracle/very_large_integers.7.res.oracle b/tests/syntax/oracle/very_large_integers.7.res.oracle
index c998aaf5b33..c6d72b6acf3 100644
--- a/tests/syntax/oracle/very_large_integers.7.res.oracle
+++ b/tests/syntax/oracle/very_large_integers.7.res.oracle
@@ -1,11 +1,5 @@
 [kernel] Parsing tests/syntax/very_large_integers.c (with preprocessing)
-[kernel] tests/syntax/very_large_integers.c:62: User Error: 
-  Invalid attribute constant: 0x80000000000000000
-[kernel] tests/syntax/very_large_integers.c:67: Warning: 
-  ignoring invalid aligned attribute: __aligned__(9223372036854775808)
-[kernel] tests/syntax/very_large_integers.c:67: Warning: 
-  ignoring invalid aligned attribute: __aligned__((9223372036854775808)+
-                                                   (9223372036854775808) )
+[kernel] tests/syntax/very_large_integers.c:63: Failure: INDEX_RANGE too large
 [kernel] User Error: stopping on file "tests/syntax/very_large_integers.c" that has errors. Add
   '-kernel-msg-key pp' for preprocessing command.
 [kernel] Frama-C aborted: invalid user input.
diff --git a/tests/syntax/oracle/very_large_integers.8.res.oracle b/tests/syntax/oracle/very_large_integers.8.res.oracle
index 1028d33119a..a78f4c463c9 100644
--- a/tests/syntax/oracle/very_large_integers.8.res.oracle
+++ b/tests/syntax/oracle/very_large_integers.8.res.oracle
@@ -1,10 +1,11 @@
 [kernel] Parsing tests/syntax/very_large_integers.c (with preprocessing)
-[kernel] tests/syntax/very_large_integers.c:67: Warning: 
+[kernel] tests/syntax/very_large_integers.c:68: User Error: 
+  Invalid attribute constant: 0x80000000000000000
+[kernel] tests/syntax/very_large_integers.c:73: Warning: 
   ignoring invalid aligned attribute: __aligned__(9223372036854775808)
-[kernel] tests/syntax/very_large_integers.c:67: Warning: 
+[kernel] tests/syntax/very_large_integers.c:73: Warning: 
   ignoring invalid aligned attribute: __aligned__((9223372036854775808)+
                                                    (9223372036854775808) )
-[kernel] Failure: Cannot represent logical integer in C: 9999999999999999999
 [kernel] User Error: stopping on file "tests/syntax/very_large_integers.c" that has errors. Add
   '-kernel-msg-key pp' for preprocessing command.
 [kernel] Frama-C aborted: invalid user input.
diff --git a/tests/syntax/oracle/very_large_integers.9.res.oracle b/tests/syntax/oracle/very_large_integers.9.res.oracle
index bcf3568e2a8..298b469609e 100644
--- a/tests/syntax/oracle/very_large_integers.9.res.oracle
+++ b/tests/syntax/oracle/very_large_integers.9.res.oracle
@@ -1,11 +1,10 @@
 [kernel] Parsing tests/syntax/very_large_integers.c (with preprocessing)
-[kernel] tests/syntax/very_large_integers.c:67: Warning: 
+[kernel] tests/syntax/very_large_integers.c:73: Warning: 
   ignoring invalid aligned attribute: __aligned__(9223372036854775808)
-[kernel] tests/syntax/very_large_integers.c:67: Warning: 
+[kernel] tests/syntax/very_large_integers.c:73: Warning: 
   ignoring invalid aligned attribute: __aligned__((9223372036854775808)+
                                                    (9223372036854775808) )
-[kernel] tests/syntax/very_large_integers.c:80: Failure: 
-  Invalid digit 9 in integer literal '09876543210' in base 8.
+[kernel] Failure: Cannot represent logical integer in C: 9999999999999999999
 [kernel] User Error: stopping on file "tests/syntax/very_large_integers.c" that has errors. Add
   '-kernel-msg-key pp' for preprocessing command.
 [kernel] Frama-C aborted: invalid user input.
diff --git a/tests/syntax/very_large_integers.c b/tests/syntax/very_large_integers.c
index 47c3629e67c..424fe4aea35 100644
--- a/tests/syntax/very_large_integers.c
+++ b/tests/syntax/very_large_integers.c
@@ -8,6 +8,7 @@
    STDOPT: #"-cpp-extra-args=-DINIT_DESIGNATOR"
    STDOPT: #"-cpp-extra-args=-DINIT_DESIGNATOR2"
    STDOPT: #"-cpp-extra-args=-DRANGE_DESIGNATOR"
+   STDOPT: #"-cpp-extra-args=-DRANGE_DESIGNATOR2"
    STDOPT: #"-cpp-extra-args=-DATTRIBUTE_CONSTANT"
    STDOPT: #"-cpp-extra-args=-DLOGIC_CONSTANT"
    STDOPT: #"-cpp-extra-args=-DLOGIC_CONSTANT_OCTAL"
@@ -40,7 +41,7 @@ void case_range() {
 #endif
 
 #ifdef CASE_RANGE2
-void case_range() {
+void case_range2() {
   switch (nondet)
   case 0 ... 10000000U:;
 }
@@ -58,6 +59,11 @@ int arr3[1] = { [9999999999999999999U] = 42 };
 int arr4[1] = { [-9999999999999999999U ... 9999999999999999999U] = 42 };
 #endif
 
+#ifdef RANGE_DESIGNATOR2
+int widths[] = { [99999999999999999 ... 999999999999999999] = 2 };
+#endif
+
+
 #ifdef ATTRIBUTE_CONSTANT
 struct acst {
   int a __attribute__((aligned(0x80000000000000000)));
-- 
GitLab