@@ -871,7 +871,6 @@ and elab_cvspec env = function
871871and elab_cvspecs env cv_specs =
872872 List. fold_left add_attributes [] (List. map (elab_cvspec env) cv_specs)
873873
874- (* Elaboration of a type declarator. C99 section 6.7.5. *)
875874and elab_return_type loc env ty =
876875 match unroll env ty with
877876 | TArray _ ->
@@ -880,14 +879,20 @@ and elab_return_type loc env ty =
880879 error loc " function cannot return function type %a" (print_typ env) ty
881880 | _ -> ()
882881
882+ (* Elaboration of a type declarator. C99 section 6.7.5. *)
883+
883884(* The [?fundef] parameter is true if we're elaborating a function definition
884885 and false otherwise. When [fundef = true], K&R function declarators
885886 are allowed, and the returned environment includes bindings for the
886887 function parameters and the struct/unions they may define.
887888 When [fundef = false], K&R function declarators are rejected
888889 and declarations in parameters are not returned. *)
889890
890- and elab_type_declarator ?(fundef = false ) loc env ty = function
891+ (* The [?param] parameter is true if we're elaborating a parameter
892+ of a function prototype, and false otherwise.
893+ This is used for checking 'static' array declarators. *)
894+
895+ and elab_type_declarator ?(fundef = false ) ?(param = false ) loc env ty = function
891896 | Cabs. JUSTBASE ->
892897 ((ty, None ), env)
893898 | Cabs. ARRAY (d , cv_specs , static , sz ) ->
@@ -897,6 +902,13 @@ and elab_type_declarator ?(fundef = false) loc env ty = function
897902 error loc " array type has incomplete element type %a" (print_typ env) ty;
898903 if wrap contains_flex_array_mem loc env ty then
899904 warning loc Flexible_array_extensions " %a may not be used as an array element due to flexible array member" (print_typ env) ty;
905+ if static then begin
906+ assert (sz <> None ); (* guaranteed by the parser *)
907+ if not param then
908+ error loc " 'static' used in array declarator outside of function prototype"
909+ else if d <> Cabs. JUSTBASE then
910+ error loc " 'static' used in non-outermost array type derivation"
911+ end ;
900912 let sz' =
901913 match sz with
902914 | None ->
@@ -913,13 +925,13 @@ and elab_type_declarator ?(fundef = false) loc env ty = function
913925 | None ->
914926 error loc " size of array is not a compile-time constant" ;
915927 Some 1L in (* produces better error messages later *)
916- elab_type_declarator ~fundef loc env (TArray (ty, sz', a)) d
928+ elab_type_declarator ~fundef ~param loc env (TArray (ty, sz', a)) d
917929 | Cabs. PTR (cv_specs , d ) ->
918930 let (ty, a) = get_nontype_attrs env ty in
919931 let a = add_attributes a (elab_cvspecs env cv_specs) in
920932 if is_function_type env ty && incl_attributes [ARestrict ] a then
921933 error loc " pointer to function type %a may not be 'restrict' qualified" (print_typ env) ty;
922- elab_type_declarator ~fundef loc env (TPtr (ty, a)) d
934+ elab_type_declarator ~fundef ~param loc env (TPtr (ty, a)) d
923935 | Cabs. PROTO (d , (params , vararg )) ->
924936 elab_return_type loc env ty;
925937 let (ty, a) = get_nontype_attrs env ty in
@@ -935,7 +947,7 @@ and elab_type_declarator ?(fundef = false) loc env ty = function
935947 if fundef && d = Cabs. JUSTBASE then
936948 ((funty, None ), env')
937949 else
938- elab_type_declarator ~fundef loc env funty d
950+ elab_type_declarator ~fundef ~param loc env funty d
939951 | Cabs. PROTO_OLD (d , params ) ->
940952 elab_return_type loc env ty;
941953 let (ty, a) = get_nontype_attrs env ty in
@@ -950,7 +962,7 @@ and elab_type_declarator ?(fundef = false) loc env ty = function
950962 end else begin
951963 if params <> [] then
952964 fatal_error loc " illegal old-style K&R function definition" ;
953- elab_type_declarator ~fundef loc env funty d
965+ elab_type_declarator ~fundef ~param loc env funty d
954966 end
955967
956968(* Elaboration of parameters in a prototype *)
@@ -971,7 +983,7 @@ and elab_parameter env (PARAM (spec, id, decl, attr, loc)) =
971983 let (sto, inl, noret, tydef, bty, env1) = elab_specifier loc env spec in
972984 if tydef then
973985 error loc " 'typedef' used in function parameter" ;
974- let ((ty, _), _) = elab_type_declarator loc env1 bty decl in
986+ let ((ty, _), _) = elab_type_declarator ~param: true loc env1 bty decl in
975987 let ty = add_attributes_type (elab_attributes env attr) ty in
976988 if sto <> Storage_default && sto <> Storage_register then
977989 error loc (* NB: 'auto' not allowed *)
@@ -1014,7 +1026,7 @@ and elab_fundef_name env spec (Name (s, decl, attr, loc)) =
10141026 error loc " 'typedef' is forbidden here" ;
10151027 let id = Env. fresh_ident s in
10161028 let ((ty, kr_params), env'') =
1017- elab_type_declarator ~fundef: true loc env' bty decl in
1029+ elab_type_declarator ~fundef: true ~param: true loc env' bty decl in
10181030 let a = elab_attributes env attr in
10191031 (id, sto, inl, noret, add_attributes_type a ty, kr_params, env', env'')
10201032
0 commit comments