diff --git a/src/kernel_internals/typing/cabs2cil.ml b/src/kernel_internals/typing/cabs2cil.ml
index 471bf33f62c10109b6778b760901dc5eb19a9dc3..826000ae54ffa9595eedb80f6b79a4ffc35b6861 100644
--- a/src/kernel_internals/typing/cabs2cil.ml
+++ b/src/kernel_internals/typing/cabs2cil.ml
@@ -3040,11 +3040,9 @@ let rec collectInitializer
         | Some len -> begin
             match constFoldToInt len with
             | Some ni when Integer.ge ni Integer.zero -> to_integer ni, false
-            | _ ->
-              abort_context
-                "Array length %a is not a compile-time constant: \
-                 no explicit initializer allowed."
-                Cil_printer.pp_exp len
+            | _ -> (* VLA cannot have initializers, and this should have
+                      been captured beforehand. *)
+              Kernel.fatal "Trying to initialize a variable-length array"
           end
         | _ ->
           (* unsized array case, length comes from initializers *)
@@ -3980,6 +3978,11 @@ let get_lval_compound_assigned op expr =
         Cil_printer.pp_lval x
   | _ -> abort_context "Expected lval for %s" op
 
+type var_decl_kind =
+  [ `FormalDecl | `GlobalDecl | `LocalDecl | `LocalStaticDecl ]
+type type_context =
+  [ var_decl_kind | `FieldDecl | `Typedef | `OnlyType ]
+
 (* The way formals are handled now might generate incorrect types, in the
    sense that they refer to a varinfo (in the case of VLA depending on a
    previously declared formal) that exists only during the call to doType.
@@ -4448,8 +4451,7 @@ let rec doSpecList loc ghost (suggestedAnonName: string)
        *)
       t'
 
-    | [Cabs.TtypeofT (specs, dt)] ->
-      doOnlyType loc ghost specs dt
+    | [Cabs.TtypeofT (specs, dt)] -> doOnlyType loc ghost specs dt
 
     | l ->
       abort_context
@@ -4471,21 +4473,22 @@ and convertCVtoAttr (src: Cabs.cvspec list) : Cabs.attribute list =
 
 and makeVarInfoCabs
     ~(ghost:bool)
-    ~(isformal: bool)
-    ~(isglobal: bool)
+    ~(kind:var_decl_kind)
     ?(isgenerated=false)
     ?(referenced=false)
     (ldecl : location)
     (bt, sto, inline, attrs)
     (n,ndt,a)
   : varinfo =
+  let isglobal = kind = `GlobalDecl || kind = `LocalStaticDecl in
+  let isformal = kind = `FormalDecl in
   let vtype, nattr =
-    doType ghost isformal (AttrName false)
-      ~allowVarSizeArrays:isformal  (* For locals we handle var-sized arrays
-                                       before makeVarInfoCabs; for formals
-                                       we do it afterwards *)
-      bt (Cabs.PARENTYPE(attrs, ndt, a)) in
-  (*Format.printf "Got yp:%a->%a(%a)@." d_type bt d_type vtype d_attrlist nattr;*)
+    doType ghost (kind:>type_context) (AttrName false)
+      ~allowVarSizeArrays:isformal
+      (* For locals we handle var-sized arrays before makeVarInfoCabs;
+         Hence, at this point only formals can have a VLA type *)
+      bt (Cabs.PARENTYPE(attrs, ndt, a))
+  in
   if hasAttribute "thread" nattr then begin
     let wkey = Kernel.wkey_inconsistent_specifier in
     let source = fst ldecl in
@@ -4509,17 +4512,13 @@ and makeVarInfoCabs
   if inline && not (isFunctionType vtype) then
     Kernel.error ~once:true ~current:true "inline for a non-function: %s" n;
   checkRestrictQualifierDeep vtype;
-  (*  log "Looking at %s(%b): (%a)@." n isformal d_attrlist nattr;*)
-  let vi = makeVarinfo ~ghost ~referenced ~temp:isgenerated ~loc:ldecl isglobal isformal n vtype
+  let vi =
+    makeVarinfo ~ghost ~referenced ~temp:isgenerated ~loc:ldecl isglobal isformal n vtype
   in
   vi.vstorage <- sto;
   vi.vattr <- nattr;
   vi.vdefined <-
     not (isFunctionType vtype) && isglobal && (sto = NoStorage || sto = Static);
-
-  (*  if false then
-      log "Created varinfo %s : %a\n" vi.vname d_type vi.vtype;*)
-
   vi
 
 (* Process a local variable declaration and allow variable-sized arrays *)
@@ -4527,12 +4526,12 @@ and makeVarSizeVarInfo ghost (ldecl : location)
     spec_res
     (n,ndt,a)
   : varinfo * chunk * exp * bool =
+  let kind = `LocalDecl in
   if not (Cil.msvcMode ()) then
     match isVariableSizedArray ghost ndt with
     | None ->
-      makeVarInfoCabs ~ghost ~isformal:false
-        ~isglobal:false
-        ldecl spec_res (n,ndt,a), empty, zero ~loc:ldecl, false
+      makeVarInfoCabs ~ghost ~kind ldecl spec_res (n,ndt,a),
+      empty, zero ~loc:ldecl, false
     | Some (ndt', se, len) ->
       (* In this case, we have changed the type from VLA to pointer: add the
          qualifier to the elements. *)
@@ -4541,13 +4540,10 @@ and makeVarSizeVarInfo ghost (ldecl : location)
           (t, sto , inline , ("ghost", []) :: attrs)
         | normal -> normal
       in
-      makeVarInfoCabs ~ghost ~isformal:false
-        ~isglobal:false
-        ldecl spec_res (n,ndt',a), se, len, true
+      makeVarInfoCabs ~ghost ~kind ldecl spec_res (n,ndt',a), se, len, true
   else
-    makeVarInfoCabs ~ghost ~isformal:false
-      ~isglobal:false
-      ldecl spec_res (n,ndt,a), empty, zero ~loc:ldecl, false
+    makeVarInfoCabs ~ghost ~kind ldecl spec_res (n,ndt,a),
+    empty, zero ~loc:ldecl, false
 
 and doAttr ghost (a: Cabs.attribute) : attribute list =
   (* Strip the leading and trailing underscore *)
@@ -4671,9 +4667,7 @@ and cabsPartitionAttributes
   in
   loop ([], [], []) attrs
 
-
-
-and doType (ghost:bool) isFuncArg
+and doType (ghost:bool) (context: type_context)
     (nameortype: attributeClass) (* This is AttrName if we are doing
                                   * the type for a name, or AttrType
                                   * if we are doing this type in a
@@ -4698,10 +4692,7 @@ and doType (ghost:bool) isFuncArg
       let a1n, a1f, a1t = partitionAttributes ~default:AttrType a1' in
       let a2' = doAttributes ghost a2 in
       let a2n, a2f, a2t = partitionAttributes ~default:nameortype a2' in
-      (*Format.printf "doType: @[a1n=%a@\na1f=%a@\na1t=%a@\na2n=%a@\na2f=%a@\na2t=%a@]@\n" d_attrlist a1n d_attrlist a1f d_attrlist a1t d_attrlist a2n d_attrlist a2f d_attrlist a2t;*)
       let bt' = cabsTypeAddAttributes a1t bt in
-      (*        log "bt' = %a@." d_type bt';*)
-
       let bt'', a1fadded =
         match unrollType bt with
         | TFun _ -> cabsTypeAddAttributes a1f bt', true
@@ -4737,7 +4728,6 @@ and doType (ghost:bool) isFuncArg
               Cil_printer.pp_attributes a2f;
           restyp
       in
-      (*        log "restyp' = %a@." d_type restyp';*)
 
       (* Now add the name attributes and return *)
       restyp', cabsAddAttributes a1n (cabsAddAttributes a2n nattr)
@@ -4848,12 +4838,28 @@ and doType (ghost:bool) isFuncArg
                  "Unable to do constant-folding on array length %a. \
                   Some CIL operations on this array may fail."
                  Cil_printer.pp_exp cst
-             else
-               Kernel.error ~once:true ~current:true
-                 "Array length %a is not a compile-time constant,@ \
-                  and currently VLAs may only have their first dimension \
-                  as variable."
-                 Cil_printer.pp_exp cst
+             else begin
+               match context with
+               | `FieldDecl ->
+                 Kernel.error ~once:true ~current:true
+                   "\"Variable length array in structure\" extension \
+                    is not supported"
+               | `GlobalDecl ->
+                 Kernel.error ~once:true ~current:true
+                   "Global arrays cannot have variable size"
+               | `LocalStaticDecl ->
+                 Kernel.error ~once:true ~current:true
+                   "Static arrays cannot have variable size"
+               | `Typedef ->
+                 Kernel.error ~once:true ~current:true
+                   "A type definition cannot be a variable-length array"
+               | `LocalDecl ->
+                 Kernel.not_yet_implemented
+                   "For multi-dimensional arrays, variable length is only \
+                    supported on the first dimension"
+               | `OnlyType | `FormalDecl ->
+                 Kernel.fatal "VLA should be accepted in this context"
+             end
            | _ -> ());
           if Cil.isZero len' && not allowZeroSizeArrays &&
              not (Cil.gccMode () || Cil.msvcMode ())
@@ -4863,7 +4869,7 @@ and doType (ghost:bool) isFuncArg
           Some len'
       in
       let al' = doAttributes ghost al in
-      if not isFuncArg && hasAttribute "static" al' then
+      if context <> `FormalDecl && hasAttribute "static" al' then
         Kernel.error ~once:true ~current:true
           "static specifier inside array argument is allowed only in \
            function argument";
@@ -4900,8 +4906,9 @@ and doType (ghost:bool) isFuncArg
       let doOneArg argl_length is_ghost (s, (n, ndt, a, cloc)) : varinfo =
         let ghost = is_ghost || ghost in
         let s' = doSpecList cloc ghost n s in
-        let vi = makeVarInfoCabs ~ghost ~isformal:true ~isglobal:false
-            (convLoc cloc) s' (n,ndt,a) in
+        let vi =
+          makeVarInfoCabs ~ghost ~kind:`FormalDecl (convLoc cloc) s' (n,ndt,a)
+        in
         if isVoidType vi.vtype then begin
           if argl_length > 1 then
             Kernel.error ~once:true ~current:true
@@ -5057,12 +5064,14 @@ and isVariableSizedArray ghost (dt: Cabs.decl_type)
   | None -> None
   | Some (se, e) -> Some (dt', se, e)
 
-and doOnlyType loc ghost (specs: Cabs.spec_elem list) (dt: Cabs.decl_type) : typ =
+and doOnlyType loc ghost specs dt =
   let bt',sto,inl,attrs = doSpecList loc ghost "" specs in
   if sto <> NoStorage || inl then
     Kernel.error ~once:true ~current:true "Storage or inline specifier in type only";
   let tres, nattr =
-    doType ghost false AttrType bt' (Cabs.PARENTYPE(attrs, dt, [])) in
+    doType ghost `OnlyType AttrType bt' (Cabs.PARENTYPE(attrs, dt, []))
+      ~allowVarSizeArrays:true
+  in
   if nattr <> [] then
     Kernel.error ~once:true ~current:true
       "Name attributes in only_type: %a" Cil_printer.pp_attributes nattr;
@@ -5106,7 +5115,7 @@ and makeCompType loc ghost (isstruct: bool)
       let allowZeroSizeArrays = Cil.gccMode () || Cil.msvcMode () in
       let ftype, fattr =
         doType
-          ~allowZeroSizeArrays ghost false (AttrName false) bt
+          ~allowZeroSizeArrays ghost `FieldDecl (AttrName false) bt
           (Cabs.PARENTYPE(attrs, ndt, a))
       in
       (* check for fields whose type is incomplete. In particular, this rules
@@ -8497,8 +8506,10 @@ and createGlobal loc ghost logic_spec ((t,s,b,attr_list) : (typ * storage * bool
   in
   (* Make a first version of the varinfo *)
   let vi_loc = convLoc cloc in
-  let vi = makeVarInfoCabs ~ghost ~isformal:false ~referenced:islibc
-      ~isglobal:true ~isgenerated vi_loc (t,s,b,attr_list) (n,ndt,a)
+  let vi =
+    makeVarInfoCabs
+      ~ghost ~kind:`GlobalDecl ~referenced:islibc ~isgenerated
+      vi_loc (t,s,b,attr_list) (n,ndt,a)
   in
   (* Add the variable to the environment before doing the initializer
    * because it might refer to the variable itself *)
@@ -8784,9 +8795,8 @@ and createLocal ghost ((_, sto, _, _) as specs)
     in
     let newname, _  = newAlphaName ghost true "" full_name in
     (* Make it global  *)
-    let vi = makeVarInfoCabs ~ghost ~isformal:false
-        ~isglobal:true
-        loc specs (n, ndt, a) in
+    let vi = makeVarInfoCabs ~ghost ~kind:`LocalStaticDecl loc specs (n, ndt, a)
+    in
     checkArray inite vi;
     vi.vname <- newname;
     let attrs = Cil.addAttribute (Attr (fc_local_static,[])) vi.vattr in
@@ -8867,8 +8877,7 @@ and createLocal ghost ((_, sto, _, _) as specs)
         let savelen =
           makeVarInfoCabs
             ~ghost
-            ~isformal:false
-            ~isglobal:false
+            ~kind:`LocalDecl
             loc
             (theMachine.typeOfSizeOf, NoStorage, false, [])
             ("__lengthof_" ^ vi.vname,JUSTBASE, [])
@@ -9078,7 +9087,7 @@ and doDecl local_env (isglobal: bool) (def: Cabs.definition) : chunk =
       if isglobal then begin
         let bt,_,_,attrs = spec_res in
         let vtype, nattr =
-          doType local_env.is_ghost false
+          doType local_env.is_ghost `GlobalDecl
             (AttrName false) bt (Cabs.PARENTYPE(attrs, ndt, a)) in
         (match filterAttributes "alias" nattr with
          | [] -> (* ordinary prototype. *)
@@ -9216,8 +9225,9 @@ and doDecl local_env (isglobal: bool) (def: Cabs.definition) : chunk =
       let bt,sto,inl,attrs = doSpecList idloc local_env.is_ghost n specs in
       !currentFunctionFDEC.svar.vinline <- inl;
       let ftyp, funattr =
-        doType local_env.is_ghost false
-          (AttrName false) bt (Cabs.PARENTYPE(attrs, dt, a)) in
+        doType local_env.is_ghost `GlobalDecl
+          (AttrName false) bt (Cabs.PARENTYPE(attrs, dt, a))
+      in
       if hasAttribute "thread" funattr then begin
         let wkey = Kernel.wkey_inconsistent_specifier in
         let source = fst funloc in
@@ -9621,7 +9631,7 @@ and doTypedef ghost ((specs, nl): Cabs.name_group) =
   let createTypedef ((n,ndt,a,_) : Cabs.name) =
     (*    E.s (error "doTypeDef") *)
     let newTyp, tattr =
-      doType ghost false AttrType bt (Cabs.PARENTYPE(attrs, ndt, a))  in
+      doType ghost `Typedef AttrType bt (Cabs.PARENTYPE(attrs, ndt, a))  in
     checkTypedefSize n newTyp;
     let tattr = fc_stdlib_attribute tattr in
     let newTyp' = cabsTypeAddAttributes tattr newTyp in
@@ -9720,7 +9730,7 @@ and doOnlyTypedef ghost (specs: Cabs.spec_elem list) : unit =
     Kernel.error ~once:true ~current:true
       "Storage or inline specifier not allowed in typedef";
   let restyp, nattr =
-    doType ghost false AttrType bt (Cabs.PARENTYPE(attrs, Cabs.JUSTBASE, []))
+    doType ghost `Typedef AttrType bt (Cabs.PARENTYPE(attrs, Cabs.JUSTBASE, []))
   in
   if nattr <> [] then
     Kernel.warning ~current:true "Ignoring identifier attribute";
@@ -10237,7 +10247,7 @@ and doStatement local_env (s : Cabs.statement) : chunk =
           let spec = doSpecList ldecl ghost n t in
           let vi =
             makeVarInfoCabs
-              ~ghost ~isformal:false ~isglobal:false ldecl spec (n,ndt,a)
+              ~ghost ~kind:`LocalDecl ldecl spec (n,ndt,a)
           in
           addLocalToEnv ghost n (EnvVar vi);
           !currentFunctionFDEC.slocals <- vi :: !currentFunctionFDEC.slocals;
diff --git a/tests/syntax/array_size.c b/tests/syntax/array_size.c
new file mode 100644
index 0000000000000000000000000000000000000000..89bec6ef204ad5945c9caf79d316c5b8cef37eb0
--- /dev/null
+++ b/tests/syntax/array_size.c
@@ -0,0 +1,39 @@
+/* run.config*
+ EXIT: 1
+   OPT: -cpp-extra-args="-DNEG_SIZE"
+   OPT: -cpp-extra-args="-DVLA_INIT1"
+   OPT: -cpp-extra-args="-DVLA_INIT2"
+   OPT: -cpp-extra-args="-DVLA_GLOB1"
+   OPT: -cpp-extra-args="-DVLA_GLOB2"
+   OPT: -cpp-extra-args="-DVLA_STRUCT"
+*/
+
+#ifdef NEG_SIZE
+int f(int t[-1]) { return t[0]; } // should raise an error
+#endif
+
+#ifdef VLA_INIT1
+void g(int size) {
+  int a[size] = { 0 }; // error: VLA can't be initialized
+}
+#endif
+
+#ifdef VLA_INIT2
+void h (int size) {
+  int a [size][2] = { { 0 } }; // same as above
+}
+#endif
+
+const int size = 42;
+
+#ifdef VLA_GLOB1
+int a[size]; // error: global arrays must have a fixed size.
+#endif
+
+#ifdef VLA_GLOB2
+int a[2][size]; // same as above
+#endif
+
+#ifdef VLA_STRUCT
+struct { int a [size]; }; // error: no VLA in struct
+#endif
diff --git a/tests/syntax/array_size.i b/tests/syntax/array_size.i
deleted file mode 100644
index e8d46d0178a748a46145d63601c3f5ba9b1711af..0000000000000000000000000000000000000000
--- a/tests/syntax/array_size.i
+++ /dev/null
@@ -1,7 +0,0 @@
-/* run.config*
- EXIT: 1
-   STDOPT:
-*/
-
-
-int f(int t[-1]) { return t[0]; } // should raise an error
diff --git a/tests/syntax/generic.c b/tests/syntax/generic.c
index 17726aab534ca3727bd74b063ccb58fd833d160c..15a9d6aa05fa9e4048c736354908ca4f41fe01bc 100644
--- a/tests/syntax/generic.c
+++ b/tests/syntax/generic.c
@@ -9,6 +9,7 @@
    STDOPT: #"-cpp-extra-args=-DINCOMPLETE_TYPE"
    STDOPT: #"-cpp-extra-args=-DINCOMPATIBLE_QUALIFIED_TYPE"
    STDOPT: #"-cpp-extra-args=-DFUNCTION_TYPE"
+   STDOPT: #"-cpp-extra-args=-DVLA"
    EXIT: 0
    STDOPT:
 */
@@ -63,6 +64,11 @@ int main() {
 #endif
 #ifdef INCOMPATIBLE_QUALIFIED_TYPE
   int a = _Generic("abc", char const *: 0);
+#endif
+#ifdef VLA
+  int x = 42;
+  int y[x];
+  int a = _Generic(y, int[x]: 0, default: 1);
 #endif
   int ok1 = _Generic("abc", char*: 0);
   int ok2 = _Generic(1.0, float: 1, double: 0);
diff --git a/tests/syntax/oracle/array_size.0.res.oracle b/tests/syntax/oracle/array_size.0.res.oracle
new file mode 100644
index 0000000000000000000000000000000000000000..fea23a0a0938e75b5581885fc29989ef383e0b94
--- /dev/null
+++ b/tests/syntax/oracle/array_size.0.res.oracle
@@ -0,0 +1,5 @@
+[kernel] Parsing array_size.c (with preprocessing)
+[kernel] array_size.c:12: User Error: Array length is negative.
+[kernel] User Error: stopping on file "array_size.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/array_size.1.res.oracle b/tests/syntax/oracle/array_size.1.res.oracle
new file mode 100644
index 0000000000000000000000000000000000000000..2cc9bdd172ac6d1eb750d7eca455cab9eba055b9
--- /dev/null
+++ b/tests/syntax/oracle/array_size.1.res.oracle
@@ -0,0 +1,6 @@
+[kernel] Parsing array_size.c (with preprocessing)
+[kernel] array_size.c:17: User Error: 
+  Variable-sized array cannot have initializer
+[kernel] User Error: stopping on file "array_size.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/array_size.2.res.oracle b/tests/syntax/oracle/array_size.2.res.oracle
new file mode 100644
index 0000000000000000000000000000000000000000..fbc09a34ed2aa0b72b59478a488aefe0399326f1
--- /dev/null
+++ b/tests/syntax/oracle/array_size.2.res.oracle
@@ -0,0 +1,6 @@
+[kernel] Parsing array_size.c (with preprocessing)
+[kernel] array_size.c:23: User Error: 
+  Variable-sized array cannot have initializer
+[kernel] User Error: stopping on file "array_size.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/array_size.3.res.oracle b/tests/syntax/oracle/array_size.3.res.oracle
new file mode 100644
index 0000000000000000000000000000000000000000..421d4380a6e78931a60d1830933bb337ae95e7b2
--- /dev/null
+++ b/tests/syntax/oracle/array_size.3.res.oracle
@@ -0,0 +1,5 @@
+[kernel] Parsing array_size.c (with preprocessing)
+[kernel] array_size.c:30: User Error: Global arrays cannot have variable size
+[kernel] User Error: stopping on file "array_size.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/array_size.4.res.oracle b/tests/syntax/oracle/array_size.4.res.oracle
new file mode 100644
index 0000000000000000000000000000000000000000..f18504df1ed797cc2f0f886c37a9da1edc893068
--- /dev/null
+++ b/tests/syntax/oracle/array_size.4.res.oracle
@@ -0,0 +1,5 @@
+[kernel] Parsing array_size.c (with preprocessing)
+[kernel] array_size.c:34: User Error: Global arrays cannot have variable size
+[kernel] User Error: stopping on file "array_size.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/array_size.5.res.oracle b/tests/syntax/oracle/array_size.5.res.oracle
new file mode 100644
index 0000000000000000000000000000000000000000..d308118b0fb6595ecb48fe215c0be5a62fd29934
--- /dev/null
+++ b/tests/syntax/oracle/array_size.5.res.oracle
@@ -0,0 +1,6 @@
+[kernel] Parsing array_size.c (with preprocessing)
+[kernel] array_size.c:38: User Error: 
+  "Variable length array in structure" extension is not supported
+[kernel] User Error: stopping on file "array_size.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/array_size.res.oracle b/tests/syntax/oracle/array_size.res.oracle
deleted file mode 100644
index ea94c308541ab9a6e185a5411e3df9086a762ef4..0000000000000000000000000000000000000000
--- a/tests/syntax/oracle/array_size.res.oracle
+++ /dev/null
@@ -1,4 +0,0 @@
-[kernel] Parsing array_size.i (no preprocessing)
-[kernel] array_size.i:7: User Error: Array length is negative.
-[kernel] User Error: stopping on file "array_size.i" that has errors.
-[kernel] Frama-C aborted: invalid user input.
diff --git a/tests/syntax/oracle/generic.1.res.oracle b/tests/syntax/oracle/generic.1.res.oracle
index c8f6605be6dcb690f616c3dd9bcdf7fc7226ea19..525bed32e1ea201e2fd17042f1b7055ef57eaa50 100644
--- a/tests/syntax/oracle/generic.1.res.oracle
+++ b/tests/syntax/oracle/generic.1.res.oracle
@@ -1,11 +1,11 @@
 [kernel] Parsing generic.c (with preprocessing)
-[kernel] generic.c:36: 
+[kernel] generic.c:37: 
   _Generic requires at least one generic association:
-  Location: line 36, between columns 10 and 25, before or at token: ;
-  34    int main() {
-  35    #ifdef NONE
-  36      int a = _Generic("abc");
+  Location: line 37, between columns 10 and 25, before or at token: ;
+  35    int main() {
+  36    #ifdef NONE
+  37      int a = _Generic("abc");
                   ^^^^^^^^^^^^^^^
-  37    #endif
-  38    #ifdef TOO_MANY_DEFAULTS
+  38    #endif
+  39    #ifdef TOO_MANY_DEFAULTS
 [kernel] Frama-C aborted: invalid user input.
diff --git a/tests/syntax/oracle/generic.10.res.oracle b/tests/syntax/oracle/generic.10.res.oracle
new file mode 100644
index 0000000000000000000000000000000000000000..70bdefa20fded77f7906a06abef980f36e8fc77e
--- /dev/null
+++ b/tests/syntax/oracle/generic.10.res.oracle
@@ -0,0 +1,32 @@
+[kernel] Parsing generic.c (with preprocessing)
+/* Generated by Frama-C */
+int foo(int i)
+{
+  int __retres;
+  __retres = 0;
+  return __retres;
+}
+
+void void_foo(int i)
+{
+  return;
+}
+
+float cbrtf(float x);
+
+int main(void)
+{
+  int __retres;
+  float tmp;
+  int ok1 = 0;
+  int ok2 = 0;
+  int ok3 = 0;
+  int ok4 = 0;
+  tmp = cbrtf(0.0f);
+  double c = (double)tmp;
+  int ok5 = 0;
+  __retres = 0;
+  return __retres;
+}
+
+
diff --git a/tests/syntax/oracle/generic.2.res.oracle b/tests/syntax/oracle/generic.2.res.oracle
index 0edc5626dfd5157572f29d022cfbf997a14fba98..592f81d34ca92c28b5b06208ad9812a2b163f9de 100644
--- a/tests/syntax/oracle/generic.2.res.oracle
+++ b/tests/syntax/oracle/generic.2.res.oracle
@@ -1,10 +1,10 @@
 [kernel] Parsing generic.c (with preprocessing)
-[kernel] generic.c:39: User Error: 
+[kernel] generic.c:40: User Error: 
   multiple default clauses in _Generic selection
-  37    #endif
-  38    #ifdef TOO_MANY_DEFAULTS
-  39      int a = _Generic("abc", default: 1, default: 1);
+  38    #endif
+  39    #ifdef TOO_MANY_DEFAULTS
+  40      int a = _Generic("abc", default: 1, default: 1);
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-  40    #endif
-  41    #ifdef TOO_MANY_COMPATIBLE
+  41    #endif
+  42    #ifdef TOO_MANY_COMPATIBLE
 [kernel] Frama-C aborted: invalid user input.
diff --git a/tests/syntax/oracle/generic.3.res.oracle b/tests/syntax/oracle/generic.3.res.oracle
index af00e69e6f9a9db9d0453d3965d5af3f92f4deb1..89f860800fa257cb2642325739dc2d86ca8c1624 100644
--- a/tests/syntax/oracle/generic.3.res.oracle
+++ b/tests/syntax/oracle/generic.3.res.oracle
@@ -1,11 +1,11 @@
 [kernel] Parsing generic.c (with preprocessing)
-[kernel] generic.c:43: User Error: 
+[kernel] generic.c:44: User Error: 
   multiple compatible types in _Generic selection:
   'my_uint' and 'unsigned int'
-  41    #ifdef TOO_MANY_COMPATIBLE
-  42      // compatibility via typedef
-  43      int a = _Generic(42, my_uint: 1, unsigned int: 2);
+  42    #ifdef TOO_MANY_COMPATIBLE
+  43      // compatibility via typedef
+  44      int a = _Generic(42, my_uint: 1, unsigned int: 2);
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-  44    #endif
-  45    #ifdef TOO_MANY_COMPATIBLE2
+  45    #endif
+  46    #ifdef TOO_MANY_COMPATIBLE2
 [kernel] Frama-C aborted: invalid user input.
diff --git a/tests/syntax/oracle/generic.4.res.oracle b/tests/syntax/oracle/generic.4.res.oracle
index 4dea267e9f5cf04b162f789e3847a6714d99c8a0..3b8bc64668e46d3130dbeadd94f7436883f59ddb 100644
--- a/tests/syntax/oracle/generic.4.res.oracle
+++ b/tests/syntax/oracle/generic.4.res.oracle
@@ -1,14 +1,14 @@
 [kernel] Parsing generic.c (with preprocessing)
-[kernel] generic.c:47: User Error: 
+[kernel] generic.c:48: User Error: 
   multiple compatible types in _Generic selection:
   'void (*)()' and 'void (*)(void)'
-  45    #ifdef TOO_MANY_COMPATIBLE2
-  46      // compatibility modulo implicit arguments
+  46    #ifdef TOO_MANY_COMPATIBLE2
+  47      // compatibility modulo implicit arguments
   
-  47      int a = _Generic(0,
-  48          void (*)():     0,
-  49          void (*)(void): 0);
+  48      int a = _Generic(0,
+  49          void (*)():     0,
+  50          void (*)(void): 0);
   
-  50    #endif
-  51    #ifdef TOO_MANY_COMPATIBLE3
+  51    #endif
+  52    #ifdef TOO_MANY_COMPATIBLE3
 [kernel] Frama-C aborted: invalid user input.
diff --git a/tests/syntax/oracle/generic.5.res.oracle b/tests/syntax/oracle/generic.5.res.oracle
index 579b9dde7959145550bcea41382a8e721f40b21d..5c1e7279049cc649936e472d3b2b116f1eb5d75f 100644
--- a/tests/syntax/oracle/generic.5.res.oracle
+++ b/tests/syntax/oracle/generic.5.res.oracle
@@ -1,15 +1,15 @@
 [kernel] Parsing generic.c (with preprocessing)
-[kernel] generic.c:54: User Error: 
+[kernel] generic.c:55: User Error: 
   controlling expression compatible with more than one association type in _Generic selection:
   controlling expression: '(void (*)())0' (type: void (*)());
   compatible types: void (*)(void), void (*)(int )
-  52      // implicit arguments compatible between first and second selector,
-  53      // but the selectors themselves are not compatible between them
+  53      // implicit arguments compatible between first and second selector,
+  54      // but the selectors themselves are not compatible between them
   
-  54      int a = _Generic((void (*)()) 0,
-  55                       void (*)(int):  0,
-  56                       void (*)(void): 0);
+  55      int a = _Generic((void (*)()) 0,
+  56                       void (*)(int):  0,
+  57                       void (*)(void): 0);
   
-  57    #endif
-  58    #ifdef INCOMPLETE_TYPE
+  58    #endif
+  59    #ifdef INCOMPLETE_TYPE
 [kernel] Frama-C aborted: invalid user input.
diff --git a/tests/syntax/oracle/generic.6.res.oracle b/tests/syntax/oracle/generic.6.res.oracle
index fbfffc1be280933ec883e33e343a303d4541dd09..c53dd9c2738d9895b66b26f0f716fc193b587cc6 100644
--- a/tests/syntax/oracle/generic.6.res.oracle
+++ b/tests/syntax/oracle/generic.6.res.oracle
@@ -1,10 +1,10 @@
 [kernel] Parsing generic.c (with preprocessing)
-[kernel] generic.c:59: User Error: 
+[kernel] generic.c:60: User Error: 
   generic association with incomplete type 'void'
-  57    #endif
-  58    #ifdef INCOMPLETE_TYPE
-  59      int a = _Generic(42, void: 1, default: 2);
+  58    #endif
+  59    #ifdef INCOMPLETE_TYPE
+  60      int a = _Generic(42, void: 1, default: 2);
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-  60    #endif
-  61    #ifdef FUNCTION_TYPE
+  61    #endif
+  62    #ifdef FUNCTION_TYPE
 [kernel] Frama-C aborted: invalid user input.
diff --git a/tests/syntax/oracle/generic.7.res.oracle b/tests/syntax/oracle/generic.7.res.oracle
index c232c3c417e6f8d49a53f25f9f116dc939d908b2..03f063c8583744504a73b16416ccd9bf9269d900 100644
--- a/tests/syntax/oracle/generic.7.res.oracle
+++ b/tests/syntax/oracle/generic.7.res.oracle
@@ -1,12 +1,12 @@
 [kernel] Parsing generic.c (with preprocessing)
-[kernel] generic.c:65: User Error: 
+[kernel] generic.c:66: User Error: 
   no compatible types and no default type in _Generic selection:
   controlling expression: '"abc"' (type: char *);
   candidate types: char const *
-  63    #endif
-  64    #ifdef INCOMPATIBLE_QUALIFIED_TYPE
-  65      int a = _Generic("abc", char const *: 0);
+  64    #endif
+  65    #ifdef INCOMPATIBLE_QUALIFIED_TYPE
+  66      int a = _Generic("abc", char const *: 0);
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-  66    #endif
-  67      int ok1 = _Generic("abc", char*: 0);
+  67    #endif
+  68    #ifdef VLA
 [kernel] Frama-C aborted: invalid user input.
diff --git a/tests/syntax/oracle/generic.8.res.oracle b/tests/syntax/oracle/generic.8.res.oracle
index fe35717281298c85c4a8ef02888473d4a3b90dce..78569285df29b0e24c4d302c3e8ec06023d6ca9c 100644
--- a/tests/syntax/oracle/generic.8.res.oracle
+++ b/tests/syntax/oracle/generic.8.res.oracle
@@ -1,11 +1,11 @@
 [kernel] Parsing generic.c (with preprocessing)
-[kernel] generic.c:62: 
+[kernel] generic.c:63: 
   syntax error:
-  Location: line 62, column 27, before or at token: int
-  60    #endif
-  61    #ifdef FUNCTION_TYPE
-  62      int a = _Generic(1, void(int): 1);
+  Location: line 63, column 27, before or at token: int
+  61    #endif
+  62    #ifdef FUNCTION_TYPE
+  63      int a = _Generic(1, void(int): 1);
                                    ^
-  63    #endif
-  64    #ifdef INCOMPATIBLE_QUALIFIED_TYPE
+  64    #endif
+  65    #ifdef INCOMPATIBLE_QUALIFIED_TYPE
 [kernel] Frama-C aborted: invalid user input.
diff --git a/tests/syntax/oracle/generic.9.res.oracle b/tests/syntax/oracle/generic.9.res.oracle
index 70bdefa20fded77f7906a06abef980f36e8fc77e..ef373d91c17e019395537108fc0b5d486723d6a9 100644
--- a/tests/syntax/oracle/generic.9.res.oracle
+++ b/tests/syntax/oracle/generic.9.res.oracle
@@ -1,32 +1,10 @@
 [kernel] Parsing generic.c (with preprocessing)
-/* Generated by Frama-C */
-int foo(int i)
-{
-  int __retres;
-  __retres = 0;
-  return __retres;
-}
-
-void void_foo(int i)
-{
-  return;
-}
-
-float cbrtf(float x);
-
-int main(void)
-{
-  int __retres;
-  float tmp;
-  int ok1 = 0;
-  int ok2 = 0;
-  int ok3 = 0;
-  int ok4 = 0;
-  tmp = cbrtf(0.0f);
-  double c = (double)tmp;
-  int ok5 = 0;
-  __retres = 0;
-  return __retres;
-}
-
-
+[kernel] generic.c:71: User Error: 
+  generic association with variably modified type 'int [x]'
+  69      int x = 42;
+  70      int y[x];
+  71      int a = _Generic(y, int[x]: 0, default: 1);
+                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+  72    #endif
+  73      int ok1 = _Generic("abc", char*: 0);
+[kernel] Frama-C aborted: invalid user input.
diff --git a/tests/syntax/oracle/sizeof.0.res.oracle b/tests/syntax/oracle/sizeof.0.res.oracle
index aa1ba789ca9fca267ec802decd82a0ed1c226e9d..4eb800ca12dab45e1da5907e8bb2d64eaaca7983 100644
--- a/tests/syntax/oracle/sizeof.0.res.oracle
+++ b/tests/syntax/oracle/sizeof.0.res.oracle
@@ -1,5 +1,6 @@
 [kernel] Parsing sizeof.c (with preprocessing)
 /* Generated by Frama-C */
+#include "assert.h"
 #include "stdint.h"
 char c = (char)1;
 char a = (char)'a';
@@ -14,4 +15,12 @@ uint64_t u64 = 6453UL;
 int v = 645201;
 float f = (float)1.;
 double d = 1.;
+void vla(int n)
+{
+  unsigned long s = sizeof(int [n]);
+  __FC_assert((s == (unsigned long)n * sizeof(int)) != 0,"sizeof.c",49,
+              "s == n * sizeof(int)");
+  return;
+}
+
 
diff --git a/tests/syntax/oracle/sizeof.1.res.oracle b/tests/syntax/oracle/sizeof.1.res.oracle
index 05c8abe3fa6d930520097aa9c3b94a8f07000f3e..f66dc175d39c9a6d08950bd025d00bf455a6c564 100644
--- a/tests/syntax/oracle/sizeof.1.res.oracle
+++ b/tests/syntax/oracle/sizeof.1.res.oracle
@@ -1,5 +1,6 @@
 [kernel] Parsing sizeof.c (with preprocessing)
 /* Generated by Frama-C */
+#include "assert.h"
 #include "stdint.h"
 char c = (char)1;
 char a = (char)'a';
@@ -14,4 +15,12 @@ uint64_t u64 = 6453ULL;
 int v = 645201;
 float f = (float)1.;
 double d = 1.;
+void vla(int n)
+{
+  unsigned long s = (unsigned long)sizeof(int [n]);
+  __FC_assert((s == (unsigned long)((unsigned int)n * sizeof(int))) != 0,
+              "sizeof.c",49,"s == n * sizeof(int)");
+  return;
+}
+
 
diff --git a/tests/syntax/oracle/vla_multidim.1.res.oracle b/tests/syntax/oracle/vla_multidim.1.res.oracle
index 09f9c527f3c5e955e651df57f5b5967bba4f1a8a..aa97a0bb5c6ca726925a4e3bc7ac37cb9fc1c8af 100644
--- a/tests/syntax/oracle/vla_multidim.1.res.oracle
+++ b/tests/syntax/oracle/vla_multidim.1.res.oracle
@@ -1,13 +1,4 @@
 [kernel] Parsing vla_multidim.c (with preprocessing)
-[kernel] vla_multidim.c:15: User Error: 
-  Array length n is not a compile-time constant,
-  and currently VLAs may only have their first dimension as variable.
-[kernel] vla_multidim.c:16: User Error: 
-  Array length n is not a compile-time constant,
-  and currently VLAs may only have their first dimension as variable.
-[kernel] vla_multidim.c:17: User Error: 
-  Array length n is not a compile-time constant,
-  and currently VLAs may only have their first dimension as variable.
-[kernel] User Error: stopping on file "vla_multidim.c" that has errors. Add '-kernel-msg-key pp'
-  for preprocessing command.
-[kernel] Frama-C aborted: invalid user input.
+[kernel] Frama-C aborted: unimplemented feature.
+  You may send a feature request at https://git.frama-c.com/pub/frama-c/issues with:
+  '[Frama-C] For multi-dimensional arrays, variable length is only supported on the first dimension'.
diff --git a/tests/syntax/oracle/vla_multidim.2.res.oracle b/tests/syntax/oracle/vla_multidim.2.res.oracle
new file mode 100644
index 0000000000000000000000000000000000000000..aa97a0bb5c6ca726925a4e3bc7ac37cb9fc1c8af
--- /dev/null
+++ b/tests/syntax/oracle/vla_multidim.2.res.oracle
@@ -0,0 +1,4 @@
+[kernel] Parsing vla_multidim.c (with preprocessing)
+[kernel] Frama-C aborted: unimplemented feature.
+  You may send a feature request at https://git.frama-c.com/pub/frama-c/issues with:
+  '[Frama-C] For multi-dimensional arrays, variable length is only supported on the first dimension'.
diff --git a/tests/syntax/oracle/vla_multidim.3.res.oracle b/tests/syntax/oracle/vla_multidim.3.res.oracle
new file mode 100644
index 0000000000000000000000000000000000000000..aa97a0bb5c6ca726925a4e3bc7ac37cb9fc1c8af
--- /dev/null
+++ b/tests/syntax/oracle/vla_multidim.3.res.oracle
@@ -0,0 +1,4 @@
+[kernel] Parsing vla_multidim.c (with preprocessing)
+[kernel] Frama-C aborted: unimplemented feature.
+  You may send a feature request at https://git.frama-c.com/pub/frama-c/issues with:
+  '[Frama-C] For multi-dimensional arrays, variable length is only supported on the first dimension'.
diff --git a/tests/syntax/sizeof.c b/tests/syntax/sizeof.c
index a27bf94011e4a4341faf3a7e948d360ce70ec2d4..7fbc16abc9fc42a0b75856d8b054f318582f9da1 100644
--- a/tests/syntax/sizeof.c
+++ b/tests/syntax/sizeof.c
@@ -3,6 +3,9 @@
    STDOPT: -machdep x86_64
    STDOPT: -machdep x86_32
 */
+
+#include <assert.h>
+
 char c = 1;
 _Static_assert(sizeof(-c) == sizeof(int), "Integer promotion with minus");
 _Static_assert(sizeof(+c) == sizeof(int), "Integer promotion with plus");
@@ -40,3 +43,8 @@ float f = 1.;
 _Static_assert(sizeof +f == sizeof(float), "Float promotion");
 double d = 1.;
 _Static_assert(sizeof +d == sizeof(double), "Double promotion");
+
+void vla(int n) {
+  unsigned long s = sizeof(int[n]);
+  assert(s == n * sizeof(int));
+}
diff --git a/tests/syntax/vla_multidim.c b/tests/syntax/vla_multidim.c
index 8308e0483842a31af16107b276f1398642f3acdf..e2c6c75e21bf1e03b0a0188067399a74cb67bbec 100644
--- a/tests/syntax/vla_multidim.c
+++ b/tests/syntax/vla_multidim.c
@@ -1,7 +1,9 @@
 /* run.config
    STDOPT: #""
-   EXIT: 1
-   STDOPT: #"-cpp-extra-args=-DMULTIVLA"
+   EXIT: 3
+   STDOPT: #"-cpp-extra-args=-DMULTIVLA1"
+   STDOPT: #"-cpp-extra-args=-DMULTIVLA2"
+   STDOPT: #"-cpp-extra-args=-DMULTIVLA3"
 */
 
 const int n = 10;
@@ -10,10 +12,15 @@ void main() {
   int a[n][42]; // single variable length dimension
   a[0][0] = 1;
   int b[a[0][0]][5][10]; // idem
-#ifdef MULTIVLA
-  // arrays with non-first variable dimensions; not currently supported
+
+// arrays with non-first variable dimensions; not currently supported
+#ifdef MULTIVLA1
   int c[n][n];
-  int d[42][n];
+#endif
+#ifdef MULTIVLA2
+int d[42][n];
+#endif
+#ifdef MULTIVLA3
   int e[1][n][9];
 #endif
 }