From 0b9f1959afeef7e9c668f80e45a34423a2285923 Mon Sep 17 00:00:00 2001 From: Baris Coslu Date: Tue, 30 Jun 2020 22:45:49 +0300 Subject: [PATCH 01/16] c99 and noreturn --- Makefile.in | 4 ++++ config.h.in | 6 ++++++ configure | 6 +++--- configure.ac | 2 +- src/cil.ml | 27 ++++++++++++++++++++----- src/cil.mli | 3 +++ src/frontc/cabs.ml | 6 ++++-- src/frontc/cabs2cil.ml | 36 ++++++++++++++++++++++++++------- src/frontc/cabsvisit.ml | 1 + src/frontc/clexer.mll | 33 +++++++++++++++++++++++++++++-- src/frontc/cparser.mly | 11 ++++++++++- src/machdep-ml.c.in | 44 ++++++++++++++++++++++++++++++++++------- src/machdepenv.ml | 4 ++++ 13 files changed, 155 insertions(+), 28 deletions(-) diff --git a/Makefile.in b/Makefile.in index 15467ce41..9377ab4ec 100644 --- a/Makefile.in +++ b/Makefile.in @@ -167,9 +167,11 @@ $(OBJDIR)/machdep.ml : src/machdep-ml.c configure.ac Makefile.in @echo " sizeof_float: int; (* Size of \"float\" *)" >> $@ @echo " sizeof_double: int; (* Size of \"double\" *)" >> $@ @echo " sizeof_longdouble: int; (* Size of \"long double\" *)" >> $@ + @echo " sizeof_float128: int; (* Size of \"__float128\" *)" >> $@ @echo " sizeof_floatcomplex: int; (* Size of \"float _Complex\" *)" >> $@ @echo " sizeof_doublecomplex: int; (* Size of \"double _Complex\" *)" >> $@ @echo " sizeof_longdoublecomplex: int; (* Size of \"long double _Complex\" *)" >> $@ + @echo " sizeof_complex128: int; (* Size of \"__complex128\" *)" >> $@ @echo " sizeof_void: int; (* Size of \"void\" *)" >> $@ @echo " sizeof_fun: int; (* Size of function *)" >> $@ @echo " size_t: string; (* Type of \"sizeof(T)\" *)" >> $@ @@ -184,9 +186,11 @@ $(OBJDIR)/machdep.ml : src/machdep-ml.c configure.ac Makefile.in @echo " alignof_float: int; (* Alignment of \"float\" *)" >> $@ @echo " alignof_double: int; (* Alignment of \"double\" *)" >> $@ @echo " alignof_longdouble: int; (* Alignment of \"long double\" *)" >> $@ + @echo " alignof_float128: int; (* Alignment of \"__float128\" *)" >> $@ @echo " alignof_floatcomplex: int; (* Alignment of \"float _Complex\" *)" >> $@ @echo " alignof_doublecomplex: int; (* Alignment of \"double _Complex\" *)" >> $@ @echo " alignof_longdoublecomplex: int; (* Alignment of \"long double _Complex\" *)" >> $@ + @echo " alignof_complex128: int; (* Alignment of \"__float128\" *)" >> $@ @echo " alignof_str: int; (* Alignment of strings *)" >> $@ @echo " alignof_fun: int; (* Alignment of function *)" >> $@ @echo " alignof_aligned: int; (* Alignment of anything with the \"aligned\" attribute *)" >> $@ diff --git a/config.h.in b/config.h.in index c43dbebe2..b1d80b44a 100644 --- a/config.h.in +++ b/config.h.in @@ -6,12 +6,18 @@ /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H +/* Define to 1 if you have the header file. */ +#undef HAVE_MATH_H + /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `mkdir' function. */ #undef HAVE_MKDIR +/* Define to 1 if you have the header file. */ +#undef HAVE_QUADMATH_H + /* Define to 1 if you have the `select' function. */ #undef HAVE_SELECT diff --git a/configure b/configure index 54b2586fe..0c6610f1d 100755 --- a/configure +++ b/configure @@ -2205,7 +2205,7 @@ ac_config_files="$ac_config_files stamp-h" # Assign here the CIL version numbers CIL_VERSION_MAJOR=1 CIL_VERSION_MINOR=7 -CIL_VERSION_REV=5 +CIL_VERSION_REV=3 CIL_VERSION=$CIL_VERSION_MAJOR.$CIL_VERSION_MINOR.$CIL_VERSION_REV # make sure I haven't forgotten to run autoconf @@ -4124,7 +4124,7 @@ if test "$OCAMLC" = "no"; then fi # if test "$OCAMLBUILD" = "no"; then -# as_fn_error $? "You must install ocamlbuild" "$LINENO" 5 +# AC_MSG_ERROR([You must install ocamlbuild]) # fi # checking for ocamllex @@ -5220,7 +5220,7 @@ $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi -for ac_header in stdlib.h strings.h sys/time.h unistd.h wchar.h stdbool.h +for ac_header in stdlib.h strings.h sys/time.h unistd.h wchar.h stdbool.h math.h quadmath.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" diff --git a/configure.ac b/configure.ac index 0e14390d2..c71dc21fe 100644 --- a/configure.ac +++ b/configure.ac @@ -168,7 +168,7 @@ AC_MSG_RESULT($UNDERSCORE_NAME) # checks for header files AC_HEADER_STDC -AC_CHECK_HEADERS(stdlib.h strings.h sys/time.h unistd.h wchar.h stdbool.h) +AC_CHECK_HEADERS(stdlib.h strings.h sys/time.h unistd.h wchar.h stdbool.h quadmath.h) # checks for typedefs, structures, and compiler characteristics AC_C_CONST diff --git a/src/cil.ml b/src/cil.ml index 6478c6dbc..fb5c1ebc6 100755 --- a/src/cil.ml +++ b/src/cil.ml @@ -302,6 +302,8 @@ and fkind = | FComplexFloat (** [float _Complex] *) | FComplexDouble (** [double _Complex] *) | FComplexLongDouble (** [long double _Complex]*) + | FFloat128 (** [__float128] *) + | FComplexFloat128 (** [__complex128] *) (** An attribute has a name and some optional parameters *) and attribute = Attr of string * attrparam list @@ -487,6 +489,7 @@ and storage = | Static | Register | Extern + | ThreadLocal (** Expressions (Side-effect free)*) @@ -1423,15 +1426,15 @@ let attributeHash: (string, attributeClass) H.t = List.iter (fun a -> H.add table a (AttrFunType false)) [ "format"; "regparm"; "longcall"; - "noinline"; "always_inline"; "gnu_inline"; "leaf"; - "artificial"; "warn_unused_result"; "nonnull"; + "noinline"; "always_inline"; "gnu_inline"; "leaf"; + "artificial"; "warn_unused_result"; "nonnull"; "c_noreturn"; ]; List.iter (fun a -> H.add table a (AttrFunType true)) - [ "stdcall";"cdecl"; "fastcall" ]; + [ "stdcall";"cdecl"; "fastcall"; ]; List.iter (fun a -> H.add table a AttrType) - [ "const"; "volatile"; "restrict"; "mode" ]; + [ "const"; "volatile"; "restrict"; "mode"; ]; table @@ -1616,9 +1619,11 @@ let typeOfRealAndImagComponents t = | FFloat -> FFloat (* [float] *) | FDouble -> FDouble (* [double] *) | FLongDouble -> FLongDouble (* [long double] *) + | FFloat128 -> FFloat128 | FComplexFloat -> FFloat | FComplexDouble -> FDouble | FComplexLongDouble -> FLongDouble + | FComplexFloat128 -> FFloat128 in TFloat (newfkind fkind, attrs) | _ -> E.s (E.bug "unexpected non-numerical type for argument to __real__") @@ -1628,9 +1633,11 @@ let getComplexFkind = function | FFloat -> FComplexFloat | FDouble -> FComplexDouble | FLongDouble -> FComplexLongDouble + | FFloat128 -> FComplexFloat128 | FComplexFloat -> FComplexFloat | FComplexDouble -> FComplexDouble | FComplexLongDouble -> FComplexLongDouble + | FComplexFloat128 -> FComplexFloat128 let var vi : lval = (Var vi, NoOffset) (* let assign vi e = Instrs(Set (var vi, e), lu) *) @@ -1703,15 +1710,18 @@ let d_fkind () = function FFloat -> text "float" | FDouble -> text "double" | FLongDouble -> text "long double" + | FFloat128 -> text "__float128" | FComplexFloat -> text "_Complex float" | FComplexDouble -> text "_Complex double" | FComplexLongDouble -> text "_Complex long double" + | FComplexFloat128 -> text "__complex128" let d_storage () = function NoStorage -> nil | Static -> text "static " | Extern -> text "extern " | Register -> text "register " + | ThreadLocal -> text "_Thread_local " (* sm: need this value below *) let mostNeg32BitInt : int64 = (Int64.of_string "-0x80000000") @@ -1794,9 +1804,11 @@ let d_const () c = FFloat -> chr 'f' | FDouble -> nil | FLongDouble -> chr 'L' + | FFloat128 -> chr 'q' | FComplexFloat -> text "iF" | FComplexDouble -> chr 'i' - | FComplexLongDouble -> text "iL") + | FComplexLongDouble -> text "iL" + | FComplexFloat128 -> text "iQ") | CEnum(_, s, ei) -> text s @@ -2202,9 +2214,11 @@ let rec alignOf_int t = | TFloat(FFloat, _) -> !M.theMachine.M.alignof_float | TFloat(FDouble, _) -> !M.theMachine.M.alignof_double | TFloat(FLongDouble, _) -> !M.theMachine.M.alignof_longdouble + | TFloat(FFloat128, _) -> !M.theMachine.M.alignof_float128 | TFloat(FComplexFloat, _) -> !M.theMachine.M.alignof_floatcomplex | TFloat(FComplexDouble, _) -> !M.theMachine.M.alignof_doublecomplex | TFloat(FComplexLongDouble, _) -> !M.theMachine.M.alignof_longdoublecomplex + | TFloat(FComplexFloat128, _) -> !M.theMachine.M.alignof_complex128 | TNamed (t, _) -> alignOf_int t.ttype | TArray (t, _, _) -> alignOf_int t | TPtr _ | TBuiltin_va_list _ -> !M.theMachine.M.alignof_ptr @@ -2465,9 +2479,11 @@ and bitsSizeOf t = | TFloat(FDouble, _) -> 8 * !M.theMachine.M.sizeof_double | TFloat(FLongDouble, _) -> 8 * !M.theMachine.M.sizeof_longdouble | TFloat(FFloat, _) -> 8 * !M.theMachine.M.sizeof_float + | TFloat(FFloat128, _) -> 8 * !M.theMachine.M.sizeof_float128 | TFloat(FComplexDouble, _) -> 8 * !M.theMachine.M.sizeof_doublecomplex | TFloat(FComplexLongDouble, _) -> 8 * !M.theMachine.M.sizeof_longdoublecomplex | TFloat(FComplexFloat, _) -> 8 * !M.theMachine.M.sizeof_floatcomplex + | TFloat(FComplexFloat128, _) -> !M.theMachine.M.sizeof_complex128 | TEnum (ei, _) -> bitsSizeOf (TInt(ei.ekind, [])) | TPtr _ -> 8 * !M.theMachine.M.sizeof_ptr | TBuiltin_va_list _ -> 8 * !M.theMachine.M.sizeof_ptr @@ -4473,6 +4489,7 @@ class defaultCilPrinterClass : cilPrinter = object (self) *) | "volatile", [] -> text "volatile", false | "restrict", [] -> text "__restrict", false + | "c_noreturn", [] -> text "_Noreturn", false | "missingproto", [] -> text "/* missing proto */", false | "cdecl", [] when !msvcMode -> text "__cdecl", false | "stdcall", [] when !msvcMode -> text "__stdcall", false diff --git a/src/cil.mli b/src/cil.mli index 3706634da..f86f7e480 100644 --- a/src/cil.mli +++ b/src/cil.mli @@ -296,6 +296,8 @@ and fkind = | FComplexFloat (** [float _Complex] *) | FComplexDouble (** [double _Complex] *) | FComplexLongDouble (** [long double _Complex]*) + | FFloat128 (** [__float128] *) + | FComplexFloat128 (** [__complex128] *) (** {b Attributes.} *) @@ -542,6 +544,7 @@ and storage = | Static | Register | Extern + | ThreadLocal (** {b Expressions.} The CIL expression language contains only the side-effect free expressions of diff --git a/src/frontc/cabs.ml b/src/frontc/cabs.ml index 04513c27c..570e2f90a 100644 --- a/src/frontc/cabs.ml +++ b/src/frontc/cabs.ml @@ -64,6 +64,7 @@ type typeSpecifier = (* Merge all specifiers into one type *) | Tint128 (* TODO needed? *) | Tfloat | Tfloat128 (* TODO needed? *) + | Tcomplex128 | Tdouble | Tsigned | Tsizet (* used temporarily to translate offsetof() *) @@ -81,10 +82,10 @@ type typeSpecifier = (* Merge all specifiers into one type *) | TtypeofT of specifier * decl_type (* GCC __typeof__ *) and storage = - NO_STORAGE | AUTO | STATIC | EXTERN | REGISTER + NO_STORAGE | AUTO | STATIC | EXTERN | REGISTER | THREADLOCAL and funspec = - INLINE | VIRTUAL | EXPLICIT + INLINE | VIRTUAL | EXPLICIT | NORETURN and cvspec = CV_CONST | CV_VOLATILE | CV_RESTRICT | CV_COMPLEX @@ -99,6 +100,7 @@ and spec_elem = | SpecCV of cvspec (* const/volatile *) | SpecAttr of attribute (* __attribute__ *) | SpecStorage of storage + | SpecFun of funspec | SpecInline | SpecType of typeSpecifier | SpecPattern of string (* specifier pattern variable *) diff --git a/src/frontc/cabs2cil.ml b/src/frontc/cabs2cil.ml index 0bbdf19c9..b32db2257 100644 --- a/src/frontc/cabs2cil.ml +++ b/src/frontc/cabs2cil.ml @@ -1256,8 +1256,12 @@ let arithmeticConversion (* c.f. ISO 6.3.1.8 *) (t2: typ) : typ = let resultingFType fkind1 t1 fkind2 t2 = (* t1 and t2 are the original types before unrollType, so TNamed is preserved if possible *) - let isComplex f = f = FComplexFloat || f = FComplexDouble || f = FComplexLongDouble in + let isComplex f = f = FComplexFloat || f = FComplexDouble || f = FComplexLongDouble || f = FComplexFloat128 in match fkind1, fkind2 with + | FComplexFloat128, _ -> t1 + | _, FComplexFloat128 -> t2 + | FFloat128, other -> if isComplex other then TFloat(FComplexFloat128, []) else t1 + | other, FFloat128 -> if isComplex other then TFloat(FComplexFloat128, []) else t2 | FComplexLongDouble, _ -> t1 | _, FComplexLongDouble -> t2 | FLongDouble, other -> if isComplex other then TFloat(FComplexLongDouble, []) else t1 @@ -2314,6 +2318,7 @@ let rec doSpecList (suggestedAnonName: string) (* This string will be part of * collected and processed separately. *) let attrs : A.attribute list ref = ref [] in (* __attribute__, etc. *) let cvattrs : A.cvspec list ref = ref [] in (* const/volatile *) + let funattrs : A.funspec list ref = ref [] in (* _Noreturn *) let doSpecElem (se: A.spec_elem) (acc: A.typeSpecifier list) @@ -2331,11 +2336,13 @@ let rec doSpecList (suggestedAnonName: string) (* This string will be part of | A.REGISTER -> Register | A.STATIC -> Static | A.EXTERN -> Extern + | A.THREADLOCAL -> ThreadLocal in storage := sto'; acc | A.SpecCV cv -> cvattrs := cv :: !cvattrs; acc + | A.SpecFun f -> funattrs := f :: !funattrs; acc | A.SpecAttr a -> attrs := a :: !attrs; acc | A.SpecType ts -> ts :: acc | A.SpecPattern _ -> E.s (E.bug "SpecPattern in cabs2cil input") @@ -2441,7 +2448,8 @@ let rec doSpecList (suggestedAnonName: string) (* This string will be part of | [A.Tdouble] -> TFloat(FDouble, []) | [A.Tlong; A.Tdouble] -> TFloat(FLongDouble, []) - | [A.Tfloat128] -> TFloat(FLongDouble, []) (* TODO: Correct? *) + | [A.Tfloat128] -> TFloat(FFloat128, []) + | [A.Tcomplex128] -> TFloat(FComplexFloat128, []) (* Now the other type specifiers *) | [A.Tnamed n] -> begin @@ -2625,7 +2633,7 @@ let rec doSpecList (suggestedAnonName: string) (* This string will be part of | _ -> E.s (error "Invalid combination of type specifiers") in - bt,!storage,!isinline,List.rev (!attrs @ (convertCVtoAttr !cvattrs)) + bt,!storage,!isinline,List.rev (!attrs @ (convertCVtoAttr !cvattrs) @ (convertFuntoAttr !funattrs)) (* given some cv attributes, convert them into named attributes for * uniform processing *) @@ -2637,6 +2645,14 @@ and convertCVtoAttr (src: A.cvspec list) : A.attribute list = | CV_RESTRICT :: tl -> ("restrict",[]) :: (convertCVtoAttr tl) | CV_COMPLEX :: tl -> ("complex",[]) :: (convertCVtoAttr tl) +and convertFuntoAttr (src: A.funspec list) : A.attribute list = + match src with + | [] -> [] + | NORETURN :: tl -> ("c_noreturn", []) :: (convertFuntoAttr tl) + | INLINE :: tl + | VIRTUAL :: tl + | EXPLICIT :: tl -> [] (* TODO? *) + and makeVarInfoCabs ~(isformal: bool) @@ -3559,10 +3575,12 @@ and doExp (asconst: bool) (* This expression is used as a constant *) String.sub str 0 (l - 1), FFloat else if hasSuffix str "D" then String.sub str 0 (l - 1), FDouble + else if hasSuffix str "Q" then + String.sub str 0 (l - 1), FFloat128 else str, FDouble in - if kind = FLongDouble then + if kind = FLongDouble || kind = FFloat128 then (* We only have 64-bit values in Ocaml *) E.log "treating long double constant %s as double constant at %a.\n" str d_loc !currentLoc; @@ -3589,6 +3607,8 @@ and doExp (asconst: bool) (* This expression is used as a constant *) String.sub str 0 (l - 2), FComplexFloat else if hasSuffix str "iD" || hasSuffix str "Di" then String.sub str 0 (l - 2), FComplexDouble + else if hasSuffix str "iQ" || hasSuffix str "Qi" then + String.sub str 0 (l - 2), FComplexFloat128 else (* A.CONST_COMPLEX always has the suffix i *) String.sub str 0 (l - 1), FComplexDouble in @@ -3677,10 +3697,12 @@ and doExp (asconst: bool) (* This expression is used as a constant *) match fkind with | FFloat | FDouble - | FLongDouble -> 8 + | FLongDouble + | FFloat128 -> 8 | FComplexFloat | FComplexDouble - | FComplexLongDouble -> 9 + | FComplexLongDouble + | FComplexFloat128 -> 9 end | TEnum _ -> 3 | TPtr _ -> 5 @@ -4382,7 +4404,7 @@ and doExp (asconst: bool) (* This expression is used as a constant *) (* if the t we determined here is complex, but the return types of all the fptrs are not, the return *) (* type should not be complex *) let isComplex t = match t with - | TFloat(f, _) -> f = FComplexFloat || f = FComplexDouble || f = FComplexLongDouble + | TFloat(f, _) -> f = FComplexFloat || f = FComplexDouble || f = FComplexLongDouble || f = FComplexFloat128 | _ -> false in if List.for_all (fun x -> not (isComplex x)) retTypes then diff --git a/src/frontc/cabsvisit.ml b/src/frontc/cabsvisit.ml index 460dc3281..ce3c99583 100644 --- a/src/frontc/cabsvisit.ml +++ b/src/frontc/cabsvisit.ml @@ -222,6 +222,7 @@ and childrenSpecElem (vis: cabsVisitor) (se: spec_elem) : spec_elem = match se with SpecTypedef | SpecInline | SpecStorage _ | SpecPattern _ -> se | SpecCV _ -> se (* cop out *) + | SpecFun _ -> se | SpecAttr a -> begin let al' = visitCabsAttribute vis a in match al' with diff --git a/src/frontc/clexer.mll b/src/frontc/clexer.mll index 8a772e372..ff8dfc1b6 100644 --- a/src/frontc/clexer.mll +++ b/src/frontc/clexer.mll @@ -140,6 +140,7 @@ let init_lexicon _ = ("float", fun loc -> FLOAT loc); ("__float128", fun loc -> FLOAT128 loc); ("_Float128", fun loc -> FLOAT128 loc); + ("__complex128", fun loc -> COMPLEX128 loc); ("double", fun loc -> DOUBLE loc); ("void", fun loc -> VOID loc); ("enum", fun loc -> ENUM loc); @@ -168,6 +169,8 @@ let init_lexicon _ = INLINE loc else IDENT ("_inline", loc)); + ("_Noreturn", fun loc -> NORETURN loc); + ("_Thread_local", fun loc -> THREADLOCAL loc); ("__attribute__", fun loc -> ATTRIBUTE loc); ("__attribute", fun loc -> ATTRIBUTE loc); (* @@ -339,6 +342,23 @@ let scan_oct_escape str = done; !the_value +(* For a given Unicode Code-point of type Int64, calculates the UTF-8 representation and returns the bytes + * in a list of 1-4 int64 values in reverse order, such that the first byte is the last element of the list *) +let utf8_representation value = + let generate_bytes n = + let first_byte = + let first_byte_prefix = match n with 1 -> 0L | 2 -> 0xC0L | 3 -> 0xE0L | 4 -> 0xF0L in + Int64.logor first_byte_prefix (Int64.shift_right_logical value (6*(n-1))) + in + let rec generate_one bytes n = + if n = 1 then bytes + else generate_one ((Int64.logor 0x80L (Int64.logand (Int64.shift_right_logical value (6*(n-2))) 0x3FL)) :: bytes) (n-1) + in + generate_one [first_byte] n + in + let num_bytes = if value <= 127L then 1 else if value <= 2047L then 2 else if value <= 65535L then 3 else 4 in + generate_bytes num_bytes + let lex_hex_escape remainder lexbuf = let prefix = scan_hex_escape (Lexing.lexeme lexbuf) in prefix :: remainder lexbuf @@ -352,6 +372,12 @@ let lex_simple_escape remainder lexbuf = let prefix = scan_escape lexchar in prefix :: remainder lexbuf +let lex_universal_escape ?is_char:(is_char=false) remainder lexbuf = + let value = scan_hex_escape (Lexing.lexeme lexbuf) in + let prefix = utf8_representation value in + if is_char then (List.hd prefix) :: remainder lexbuf + else List.rev_append prefix (remainder lexbuf) + let lex_unescaped remainder lexbuf = let prefix = Int64.of_int (Char.code (Lexing.lexeme_char lexbuf 0)) in prefix :: remainder lexbuf @@ -435,17 +461,18 @@ let binexponent = ['p' 'P'] ['+' '-']? decdigit+ let hexfloat = hexprefix hexfraction binexponent | hexprefix hexdigit+ binexponent -let floatsuffix = ['f' 'F' 'l' 'L'] +let floatsuffix = ['f' 'F' 'l' 'L' 'q' 'Q'] let floatnum = (decfloat | hexfloat) floatsuffix? let complexnum = (decfloat | hexfloat) ((['i' 'I'] floatsuffix) | (floatsuffix? ['i' 'I'])) -let ident = (letter|'_'|'$')(letter|decdigit|'_'|'$')* let blank = [' ' '\t' '\012' '\r']+ let escape = '\\' _ let hex_escape = '\\' ['x' 'X'] hexdigit+ let oct_escape = '\\' octdigit octdigit? octdigit? +let universal_escape = '\\' ('u' hexdigit hexdigit hexdigit hexdigit | 'U' hexdigit hexdigit hexdigit hexdigit hexdigit hexdigit hexdigit hexdigit) +let ident = (letter|'_'|'$'|universal_escape)(letter|decdigit|'_'|'$'|universal_escape)* (* Pragmas that are not parsed by CIL. We lex them as PRAGMA_LINE tokens *) let no_parse_pragma = @@ -669,6 +696,7 @@ and str = parse | hex_escape {addLexeme lexbuf; lex_hex_escape str lexbuf} | oct_escape {addLexeme lexbuf; lex_oct_escape str lexbuf} | escape {addLexeme lexbuf; lex_simple_escape str lexbuf} +| universal_escape {addLexeme lexbuf; lex_universal_escape str lexbuf} | _ {addLexeme lexbuf; lex_unescaped str lexbuf} and chr = parse @@ -676,6 +704,7 @@ and chr = parse | hex_escape {lex_hex_escape chr lexbuf} | oct_escape {lex_oct_escape chr lexbuf} | escape {lex_simple_escape chr lexbuf} +| universal_escape {lex_universal_escape ~is_char:true chr lexbuf} | _ {lex_unescaped chr lexbuf} and msasm = parse diff --git a/src/frontc/cparser.mly b/src/frontc/cparser.mly index f5cbd24b2..45a392b18 100644 --- a/src/frontc/cparser.mly +++ b/src/frontc/cparser.mly @@ -256,7 +256,8 @@ let transformOffsetOf (speclist, dtype) member = %token EOF %token CHAR INT BOOL DOUBLE FLOAT VOID INT64 INT32 -%token INT128 FLOAT128 COMPLEX /* C99 */ +%token INT128 FLOAT128 COMPLEX COMPLEX128 /* C99 */ +%token NORETURN THREADLOCAL/* C11 */ %token ENUM STRUCT TYPEDEF UNION %token SIGNED UNSIGNED LONG SHORT %token VOLATILE EXTERN STATIC CONST RESTRICT AUTO REGISTER HIDDEN @@ -955,10 +956,12 @@ decl_spec_list: /* ISO 6.7 */ | STATIC decl_spec_list_opt { SpecStorage STATIC :: $2, $1 } | AUTO decl_spec_list_opt { SpecStorage AUTO :: $2, $1 } | REGISTER decl_spec_list_opt { SpecStorage REGISTER :: $2, $1} +| THREADLOCAL decl_spec_list_opt { SpecStorage THREADLOCAL :: $2, $1} /* ISO 6.7.2 */ | type_spec decl_spec_list_opt_no_named { SpecType (fst $1) :: $2, snd $1 } /* ISO 6.7.4 */ | INLINE decl_spec_list_opt { SpecInline :: $2, $1 } +| funspec decl_spec_list_opt { (fst $1) :: $2, snd $1 } | cvspec decl_spec_list_opt { (fst $1) :: $2, snd $1 } | attribute_nocv decl_spec_list_opt { SpecAttr (fst $1) :: $2, snd $1 } /* specifier pattern variable (must be last in spec list) */ @@ -989,6 +992,7 @@ type_spec: /* ISO 6.7.2 */ | INT128 { Tint128, $1 } | FLOAT { Tfloat, $1 } | FLOAT128 { Tfloat128, $1 } +| COMPLEX128 { Tcomplex128, $1} | DOUBLE { Tdouble, $1 } /* | COMPLEX FLOAT { Tfloat, $2 } */ /* | COMPLEX FLOAT128{ Tfloat128, $2 } */ @@ -1297,6 +1301,11 @@ cvspec: | COMPLEX { SpecCV(CV_COMPLEX), $1 } ; +/* function specifiers */ +funspec: + NORETURN { SpecFun(NORETURN), $1 } +; + /*** GCC attributes ***/ attributes: /* empty */ { []} diff --git a/src/machdep-ml.c.in b/src/machdep-ml.c.in index 2fb691d45..91f5a5c94 100644 --- a/src/machdep-ml.c.in +++ b/src/machdep-ml.c.in @@ -54,6 +54,12 @@ typedef int bool; #endif +#ifdef HAVE_QUADMATH_H +#include +#else +typedef long double _Complex __complex128; +#endif + #ifdef HAVE_INTTYPES_H #include #endif @@ -101,8 +107,8 @@ int main(int argc, char **argv) { int env = argc == 2 && !strcmp(argv[1], "--env"); int alignof_short, alignof_int, alignof_long, alignof_ptr, alignof_enum, - alignof_float, alignof_double, alignof_longdouble, - alignof_floatcomplex, alignof_doublecomplex, alignof_longdoublecomplex, + alignof_float, alignof_double, alignof_longdouble, alignof_float128, + alignof_floatcomplex, alignof_doublecomplex, alignof_longdoublecomplex, alignof_complex128, sizeof_fun, alignof_fun, alignof_str, alignof_aligned, alignof_longlong, little_endian, char_is_unsigned, alignof_bool; @@ -196,6 +202,15 @@ int main(int argc, char **argv) }; alignof_longdouble = (intptr_t)(&((struct s1*)0)->ld); } + + // The alignment of __float128 + { + struct s1 { + char c; + __float128 f1; + }; + alignof_float128 = (intptr_t)(&((struct s1*)0)->f1); + } // The alignment of a float complex { @@ -224,6 +239,15 @@ int main(int argc, char **argv) alignof_longdoublecomplex = (intptr_t)(&((struct s1*)0)->ld); } + // The alignment of __complex128 + { + struct s1 { + char c; + __complex128 c1; + }; + alignof_complex128 = (intptr_t)(&((struct s1*)0)->c1); + } + alignof_str = __alignof("a string"); alignof_fun = __alignof(main); @@ -260,8 +284,9 @@ int main(int argc, char **argv) { fprintf(stderr, "Generating CIL_MACHINE machine dependency information string (for CIL)\n"); printf("short=%d,%d int=%d,%d long=%d,%d long_long=%d,%d pointer=%d,%d " - "alignof_enum=%d float=%d,%d double=%d,%d long_double=%d,%d float_complex=%d,%d double_complex=%d,%d long_double_complex=%d,%d void=%d " - "bool=%d,%d fun=%d,%d alignof_string=%d max_alignment=%d size_t=%s " + "alignof_enum=%d float=%d,%d double=%d,%d long_double=%d,%d float128=%d,%d " + "float_complex=%d,%d double_complex=%d,%d long_double_complex=%d,%d complex128=%d,%d " + "void=%d bool=%d,%d fun=%d,%d alignof_string=%d max_alignment=%d size_t=%s " "wchar_t=%s char_signed=%s const_string_literals=%s " "big_endian=%s __thread_is_keyword=%s __builtin_va_list=%s " "underscore_name=%s\n", @@ -269,9 +294,10 @@ int main(int argc, char **argv) (int)sizeof(long), alignof_long, (int)sizeof(long long), alignof_longlong, (int)sizeof(int *), alignof_ptr, alignof_enum, (int)sizeof(float), alignof_float, (int)sizeof(double), alignof_double, - (int)sizeof(long double), alignof_longdouble, (int)sizeof(float _Complex), alignof_floatcomplex, (int)sizeof(double _Complex), alignof_doublecomplex, - (int)sizeof(long double _Complex), alignof_longdoublecomplex, (int)sizeof(void), - (int)sizeof(bool), alignof_bool, + (int)sizeof(long double), alignof_longdouble, (int)sizeof(__float128), alignof_float128, + (int)sizeof(float _Complex), alignof_floatcomplex, (int)sizeof(double _Complex), alignof_doublecomplex, + (int)sizeof(long double _Complex), alignof_longdoublecomplex, (int)sizeof(__complex128), alignof_complex128, + (int)sizeof(void), (int)sizeof(bool), alignof_bool, sizeof_fun, alignof_fun, alignof_str, alignof_aligned, underscore(TYPE_SIZE_T), underscore(TYPE_WCHAR_T), char_is_unsigned ? "false" : "true", CONST_STRING_LITERALS, @@ -297,9 +323,11 @@ int main(int argc, char **argv) printf("\t sizeof_float = %d;\n", (int)sizeof(float)); printf("\t sizeof_double = %d;\n", (int)sizeof(double)); printf("\t sizeof_longdouble = %d;\n", (int)sizeof(long double)); + printf("\t sizeof_float128 = %d;\n", (int)sizeof(__float128)); printf("\t sizeof_floatcomplex = %d;\n", (int)sizeof(float _Complex)); printf("\t sizeof_doublecomplex = %d;\n", (int)sizeof(double _Complex)); printf("\t sizeof_longdoublecomplex = %d;\n", (int)sizeof(long double _Complex)); + printf("\t sizeof_complex128 = %d;\n", (int)sizeof(__complex128)); printf("\t sizeof_void = %d;\n", (int)sizeof(void)); printf("\t sizeof_fun = %d;\n", (int)sizeof_fun); printf("\t size_t = \"%s\";\n", TYPE_SIZE_T); @@ -314,9 +342,11 @@ int main(int argc, char **argv) printf("\t alignof_float = %d;\n", alignof_float); printf("\t alignof_double = %d;\n", alignof_double); printf("\t alignof_longdouble = %d;\n", alignof_longdouble); + printf("\t alignof_float128 = %d;\n", alignof_float128); printf("\t alignof_floatcomplex = %d;\n", alignof_floatcomplex); printf("\t alignof_doublecomplex = %d;\n", alignof_doublecomplex); printf("\t alignof_longdoublecomplex = %d;\n", alignof_longdoublecomplex); + printf("\t alignof_complex128 = %d;\n", alignof_complex128); printf("\t alignof_str = %d;\n", alignof_str); printf("\t alignof_fun = %d;\n", alignof_fun); printf("\t alignof_aligned = %d;\n", alignof_aligned); diff --git a/src/machdepenv.ml b/src/machdepenv.ml index 2707946b7..bf2731248 100644 --- a/src/machdepenv.ml +++ b/src/machdepenv.ml @@ -81,6 +81,10 @@ let modelParse (s:string) : mach = alignof_longdouble = getAlignof entries "long_double"; sizeof_longdoublecomplex = getSizeof entries "long_double_complex"; alignof_longdoublecomplex = getAlignof entries "long_double_complex"; + sizeof_float128 = getSizeof entries "float128"; + alignof_float128 = getAlignof entries "float128"; + sizeof_complex128 = getSizeof entries "complex128"; + alignof_complex128 = getAlignof entries "complex128"; sizeof_void = getSizeof entries "void"; sizeof_fun = getSizeof entries "fun"; alignof_fun = getAlignof entries "fun"; From 6089339631d2a42515a3947c22762315408e9968 Mon Sep 17 00:00:00 2001 From: Baris Coslu Date: Wed, 29 Jul 2020 19:03:27 +0300 Subject: [PATCH 02/16] char16_t and char32_t character constants --- Makefile.in | 2 + config.h.in | 12 +- configure | 472 +++++++++++++++++++++++++++++++++++++++- configure.ac | 4 +- m4/cil.m4 | 1 + src/cil.ml | 17 +- src/cil.mli | 9 +- src/frontc/cabs.ml | 5 +- src/frontc/cabs2cil.ml | 59 +++-- src/frontc/cabsvisit.ml | 2 +- src/frontc/clexer.mll | 9 + src/frontc/cparser.mly | 8 +- src/machdep-ml.c.in | 6 +- src/machdepenv.ml | 2 + 14 files changed, 569 insertions(+), 39 deletions(-) diff --git a/Makefile.in b/Makefile.in index 9377ab4ec..4beee788d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -176,6 +176,8 @@ $(OBJDIR)/machdep.ml : src/machdep-ml.c configure.ac Makefile.in @echo " sizeof_fun: int; (* Size of function *)" >> $@ @echo " size_t: string; (* Type of \"sizeof(T)\" *)" >> $@ @echo " wchar_t: string; (* Type of \"wchar_t\" *)" >> $@ + @echo " char16_t: string; (* Type of \"char16_t\" *)" >> $@ + @echo " char32_t: string; (* Type of \"char32_t\" *)" >> $@ @echo " alignof_short: int; (* Alignment of \"short\" *)" >> $@ @echo " alignof_int: int; (* Alignment of \"int\" *)" >> $@ @echo " alignof_bool: int; (* Alignment of \"_Bool\" *)" >> $@ diff --git a/config.h.in b/config.h.in index b1d80b44a..26d6cbaeb 100644 --- a/config.h.in +++ b/config.h.in @@ -6,9 +6,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H -/* Define to 1 if you have the header file. */ -#undef HAVE_MATH_H - /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H @@ -48,6 +45,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H +/* Define to 1 if you have the header file. */ +#undef HAVE_UCHAR_H + /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H @@ -81,6 +81,12 @@ /* Define to 1 if you can safely include both and . */ #undef TIME_WITH_SYS_TIME +/* Real integer type corresponding to char16_t. */ +#undef TYPE_CHAR16_T + +/* Real integer type corresponding to char32_t. */ +#undef TYPE_CHAR32_T + /* Real integer type corresponding to size_t. */ #undef TYPE_SIZE_T diff --git a/configure b/configure index 0c6610f1d..711026cd3 100755 --- a/configure +++ b/configure @@ -5220,7 +5220,7 @@ $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi -for ac_header in stdlib.h strings.h sys/time.h unistd.h wchar.h stdbool.h math.h quadmath.h +for ac_header in stdlib.h strings.h sys/time.h unistd.h wchar.h stdbool.h quadmath.h uchar.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" @@ -5519,6 +5519,7 @@ $as_echo_n "checking for real definition of size_t... " >&6; } #include #include +#include /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5538,6 +5539,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5559,6 +5561,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5578,6 +5581,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5599,6 +5603,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5618,6 +5623,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5639,6 +5645,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5658,6 +5665,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5679,6 +5687,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5698,6 +5707,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5734,6 +5744,7 @@ $as_echo_n "checking for real definition of wchar_t... " >&6; } #include #include +#include /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5753,6 +5764,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5774,6 +5786,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5793,6 +5806,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5814,6 +5828,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5833,6 +5848,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5854,6 +5870,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5873,6 +5890,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5894,6 +5912,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5913,6 +5932,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5938,6 +5958,456 @@ _ACEOF $as_echo "$real_type" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for real definition of char16_t" >&5 +$as_echo_n "checking for real definition of char16_t... " >&6; } + real_type='' + + + if test -z "$real_type"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +/* We define a prototype with one type and the function with + another type. This will result in compilation error + unless the types are really identical. */ +int foo(int x); +char16_t foo(char16_t x) { return x; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + real_type='int' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + + + if test -z "$real_type"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +/* We define a prototype with one type and the function with + another type. This will result in compilation error + unless the types are really identical. */ +unsigned int foo(unsigned int x); +char16_t foo(char16_t x) { return x; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + real_type='unsigned int' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + + + + + if test -z "$real_type"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +/* We define a prototype with one type and the function with + another type. This will result in compilation error + unless the types are really identical. */ +long foo(long x); +char16_t foo(char16_t x) { return x; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + real_type='long' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + + + if test -z "$real_type"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +/* We define a prototype with one type and the function with + another type. This will result in compilation error + unless the types are really identical. */ +unsigned long foo(unsigned long x); +char16_t foo(char16_t x) { return x; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + real_type='unsigned long' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + + + + + if test -z "$real_type"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +/* We define a prototype with one type and the function with + another type. This will result in compilation error + unless the types are really identical. */ +long long foo(long long x); +char16_t foo(char16_t x) { return x; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + real_type='long long' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + + + if test -z "$real_type"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +/* We define a prototype with one type and the function with + another type. This will result in compilation error + unless the types are really identical. */ +unsigned long long foo(unsigned long long x); +char16_t foo(char16_t x) { return x; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + real_type='unsigned long long' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + + + + + if test -z "$real_type"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +/* We define a prototype with one type and the function with + another type. This will result in compilation error + unless the types are really identical. */ +short foo(short x); +char16_t foo(char16_t x) { return x; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + real_type='short' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + + + if test -z "$real_type"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +/* We define a prototype with one type and the function with + another type. This will result in compilation error + unless the types are really identical. */ +unsigned short foo(unsigned short x); +char16_t foo(char16_t x) { return x; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + real_type='unsigned short' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + + + + + if test -z "$real_type"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +/* We define a prototype with one type and the function with + another type. This will result in compilation error + unless the types are really identical. */ +char foo(char x); +char16_t foo(char16_t x) { return x; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + real_type='char' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + + + if test -z "$real_type"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +/* We define a prototype with one type and the function with + another type. This will result in compilation error + unless the types are really identical. */ +unsigned char foo(unsigned char x); +char16_t foo(char16_t x) { return x; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + real_type='unsigned char' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + + + if test -z "$real_type"; then + as_fn_error $? "cannot find definition of char16_t" "$LINENO" 5 + fi + +cat >>confdefs.h <<_ACEOF +#define TYPE_CHAR16_T "$real_type" +_ACEOF + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $real_type" >&5 +$as_echo "$real_type" >&6; } + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for real definition of char32_t" >&5 +$as_echo_n "checking for real definition of char32_t... " >&6; } + real_type='' + + + if test -z "$real_type"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +/* We define a prototype with one type and the function with + another type. This will result in compilation error + unless the types are really identical. */ +int foo(int x); +char32_t foo(char32_t x) { return x; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + real_type='int' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + + + if test -z "$real_type"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +/* We define a prototype with one type and the function with + another type. This will result in compilation error + unless the types are really identical. */ +unsigned int foo(unsigned int x); +char32_t foo(char32_t x) { return x; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + real_type='unsigned int' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + + + + + if test -z "$real_type"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +/* We define a prototype with one type and the function with + another type. This will result in compilation error + unless the types are really identical. */ +long foo(long x); +char32_t foo(char32_t x) { return x; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + real_type='long' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + + + if test -z "$real_type"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +/* We define a prototype with one type and the function with + another type. This will result in compilation error + unless the types are really identical. */ +unsigned long foo(unsigned long x); +char32_t foo(char32_t x) { return x; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + real_type='unsigned long' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + + + + + if test -z "$real_type"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +/* We define a prototype with one type and the function with + another type. This will result in compilation error + unless the types are really identical. */ +long long foo(long long x); +char32_t foo(char32_t x) { return x; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + real_type='long long' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + + + if test -z "$real_type"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +/* We define a prototype with one type and the function with + another type. This will result in compilation error + unless the types are really identical. */ +unsigned long long foo(unsigned long long x); +char32_t foo(char32_t x) { return x; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + real_type='unsigned long long' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + + + + + if test -z "$real_type"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +/* We define a prototype with one type and the function with + another type. This will result in compilation error + unless the types are really identical. */ +short foo(short x); +char32_t foo(char32_t x) { return x; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + real_type='short' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + + + if test -z "$real_type"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +/* We define a prototype with one type and the function with + another type. This will result in compilation error + unless the types are really identical. */ +unsigned short foo(unsigned short x); +char32_t foo(char32_t x) { return x; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + real_type='unsigned short' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + + + + + if test -z "$real_type"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +/* We define a prototype with one type and the function with + another type. This will result in compilation error + unless the types are really identical. */ +char foo(char x); +char32_t foo(char32_t x) { return x; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + real_type='char' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + + + if test -z "$real_type"; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include +/* We define a prototype with one type and the function with + another type. This will result in compilation error + unless the types are really identical. */ +unsigned char foo(unsigned char x); +char32_t foo(char32_t x) { return x; } +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + real_type='unsigned char' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + fi + + + if test -z "$real_type"; then + as_fn_error $? "cannot find definition of char32_t" "$LINENO" 5 + fi + +cat >>confdefs.h <<_ACEOF +#define TYPE_CHAR32_T "$real_type" +_ACEOF + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $real_type" >&5 +$as_echo "$real_type" >&6; } + + # ----------------- finish up ------------------- # names of the variables that get substituted in files; for example, # write @CIL_VERSION@ somewhere in a written file to get it substituted diff --git a/configure.ac b/configure.ac index c71dc21fe..fe07d50ff 100644 --- a/configure.ac +++ b/configure.ac @@ -168,7 +168,7 @@ AC_MSG_RESULT($UNDERSCORE_NAME) # checks for header files AC_HEADER_STDC -AC_CHECK_HEADERS(stdlib.h strings.h sys/time.h unistd.h wchar.h stdbool.h quadmath.h) +AC_CHECK_HEADERS(stdlib.h strings.h sys/time.h unistd.h wchar.h stdbool.h quadmath.h uchar.h) # checks for typedefs, structures, and compiler characteristics AC_C_CONST @@ -183,6 +183,8 @@ AC_CHECK_FUNCS(mkdir select socket __sysv_signal) # Find out the true definitions of some integer types CIL_CHECK_INTEGER_TYPE(size_t, TYPE_SIZE_T) CIL_CHECK_INTEGER_TYPE(wchar_t, TYPE_WCHAR_T) +CIL_CHECK_INTEGER_TYPE(char16_t, TYPE_CHAR16_T) +CIL_CHECK_INTEGER_TYPE(char32_t, TYPE_CHAR32_T) # ----------------- finish up ------------------- # names of the variables that get substituted in files; for example, diff --git a/m4/cil.m4 b/m4/cil.m4 index 8ca22021c..c0496f756 100644 --- a/m4/cil.m4 +++ b/m4/cil.m4 @@ -5,6 +5,7 @@ AC_DEFUN([__CIL_CHECK_INTEGER_TYPE_TYPE], [ AC_COMPILE_IFELSE([AC_LANG_SOURCE([ #include #include +#include /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ diff --git a/src/cil.ml b/src/cil.ml index fb5c1ebc6..3c1e40d1c 100755 --- a/src/cil.ml +++ b/src/cil.ml @@ -435,6 +435,8 @@ and varinfo = { mutable vinline: bool; (** Whether this varinfo is for an inline function. *) + mutable vthreadlocal: bool; + mutable vdecl: location; (** Location of variable declaration *) vinit: initinfo; @@ -489,7 +491,6 @@ and storage = | Static | Register | Extern - | ThreadLocal (** Expressions (Side-effect free)*) @@ -1288,10 +1289,13 @@ let upointType = ref voidType (* An integer type that fits a pointer difference. Initialized by initCIL *) let ptrdiffType = ref voidType -(* An integer type that fits wchar_t. Initialized by initCIL *) +(* Integer types that fit wchar_t, char16_t and char32_t. Initialized by initCIL *) let wcharKind = ref IChar let wcharType = ref voidType - +let char16Kind = ref IChar +let char16Type = ref voidType +let char32Kind = ref IChar +let char32Type = ref voidType (* An integer type that is the type of sizeof. Initialized by initCIL *) let typeOfSizeOf = ref voidType @@ -1721,7 +1725,6 @@ let d_storage () = function | Static -> text "static " | Extern -> text "extern " | Register -> text "register " - | ThreadLocal -> text "_Thread_local " (* sm: need this value below *) let mostNeg32BitInt : int64 = (Int64.of_string "-0x80000000") @@ -3431,6 +3434,7 @@ class defaultCilPrinterClass : cilPrinter = object (self) let stom, rest = separateStorageModifiers v.vattr in (* First the storage modifiers *) text (if v.vinline then "__inline " else "") + ++ text (if v.vthreadlocal then "_Thread_local " else "") ++ d_storage () v.vstorage ++ (self#pAttrs () stom) ++ (self#pType (Some (text v.vname)) () v.vtype) @@ -5055,6 +5059,7 @@ let makeVarinfo global name ?init typ = vdecl = lu; vinit = {init=init}; vinline = false; + vthreadlocal = false; vattr = []; vstorage = NoStorage; vaddrof = false; @@ -7038,6 +7043,10 @@ let initCIL () = typeOfSizeOf := TInt(!kindOfSizeOf, []); wcharKind := findIkindName !M.theMachine.M.wchar_t; wcharType := TInt(!wcharKind, []); + char16Kind := findIkindName !M.theMachine.M.char16_t; + char16Type := TInt(!char16Kind, []); + char32Kind := findIkindName !M.theMachine.M.char32_t; + char32Type := TInt(!char32Kind, []); char_is_unsigned := !M.theMachine.M.char_is_unsigned; little_endian := !M.theMachine.M.little_endian; underscore_name := !M.theMachine.M.underscore_name; diff --git a/src/cil.mli b/src/cil.mli index f86f7e480..d913a5e70 100644 --- a/src/cil.mli +++ b/src/cil.mli @@ -494,6 +494,8 @@ and varinfo = { mutable vinline: bool; (** Whether this varinfo is for an inline function. *) + mutable vthreadlocal: bool; + mutable vdecl: location; (** Location of variable declaration. *) @@ -544,7 +546,6 @@ and storage = | Static | Register | Extern - | ThreadLocal (** {b Expressions.} The CIL expression language contains only the side-effect free expressions of @@ -1347,10 +1348,14 @@ val charType: typ (** char * *) val charPtrType: typ -(** wchar_t (depends on architecture) and is set when you call +(** wchar_t, char16_t and char32_t (depends on architecture) and is set when you call * {!Cil.initCIL}. *) val wcharKind: ikind ref val wcharType: typ ref +val char16Kind: ikind ref +val char16Type: typ ref +val char32Kind: ikind ref +val char32Type: typ ref (** char const * *) val charConstPtrType: typ diff --git a/src/frontc/cabs.ml b/src/frontc/cabs.ml index 570e2f90a..925dfb5f1 100644 --- a/src/frontc/cabs.ml +++ b/src/frontc/cabs.ml @@ -82,7 +82,7 @@ type typeSpecifier = (* Merge all specifiers into one type *) | TtypeofT of specifier * decl_type (* GCC __typeof__ *) and storage = - NO_STORAGE | AUTO | STATIC | EXTERN | REGISTER | THREADLOCAL + NO_STORAGE | AUTO | STATIC | EXTERN | REGISTER and funspec = INLINE | VIRTUAL | EXPLICIT | NORETURN @@ -102,6 +102,7 @@ and spec_elem = | SpecStorage of storage | SpecFun of funspec | SpecInline + | SpecThreadLocal | SpecType of typeSpecifier | SpecPattern of string (* specifier pattern variable *) @@ -289,6 +290,8 @@ and constant = | CONST_COMPLEX of string (* the textual representation *) | CONST_CHAR of int64 list | CONST_WCHAR of int64 list + | CONST_CHAR16 of int64 list + | CONST_CHAR32 of int64 list | CONST_STRING of string | CONST_WSTRING of int64 list (* ww: wstrings are stored as an int64 list at this point because diff --git a/src/frontc/cabs2cil.ml b/src/frontc/cabs2cil.ml index b32db2257..ea9c6a849 100644 --- a/src/frontc/cabs2cil.ml +++ b/src/frontc/cabs2cil.ml @@ -584,6 +584,8 @@ let alphaConvertVarAndAddToEnv (addtoenv: bool) (vi: varinfo) : varinfo = (* Store all locals in the slocals (in reversed order). We'll reverse them * and take out the formals at the end of the function *) if not vi.vglob then + if vi.vthreadlocal && vi.vstorage = NoStorage then + E.s (error "Declaration specifiers of %s in block scope include _Thread_local but do not include static or extern" vi.vname); !currentFunctionFDEC.slocals <- newvi :: !currentFunctionFDEC.slocals; (if addtoenv then @@ -2304,9 +2306,10 @@ let rec doSpecList (suggestedAnonName: string) (* This string will be part of (specs: A.spec_elem list) (* Returns the base type, the storage, whether it is inline and the * (unprocessed) attributes *) - : typ * storage * bool * A.attribute list = + : typ * storage * bool * bool * A.attribute list = (* Do one element and collect the type specifiers *) let isinline = ref false in (* If inline appears *) + let isthreadlocal = ref false in (* The storage is placed here *) let storage : storage ref = ref NoStorage in @@ -2325,9 +2328,13 @@ let rec doSpecList (suggestedAnonName: string) (* This string will be part of : A.typeSpecifier list = match se with A.SpecTypedef -> acc - | A.SpecInline -> isinline := true; acc + | A.SpecInline -> isinline := true; acc + | A.SpecThreadLocal -> + if !storage <> NoStorage && !storage <> Extern && !storage <> Static then + E.s (error "Multiple storage specifiers"); + isthreadlocal := true; acc | A.SpecStorage st -> - if !storage <> NoStorage then + if !storage <> NoStorage || !isthreadlocal && st <> STATIC && st <> EXTERN then E.s (error "Multiple storage specifiers"); let sto' = match st with @@ -2336,7 +2343,6 @@ let rec doSpecList (suggestedAnonName: string) (* This string will be part of | A.REGISTER -> Register | A.STATIC -> Static | A.EXTERN -> Extern - | A.THREADLOCAL -> ThreadLocal in storage := sto'; acc @@ -2633,7 +2639,7 @@ let rec doSpecList (suggestedAnonName: string) (* This string will be part of | _ -> E.s (error "Invalid combination of type specifiers") in - bt,!storage,!isinline,List.rev (!attrs @ (convertCVtoAttr !cvattrs) @ (convertFuntoAttr !funattrs)) + bt,!storage,!isinline, !isthreadlocal, List.rev (!attrs @ (convertCVtoAttr !cvattrs) @ (convertFuntoAttr !funattrs)) (* given some cv attributes, convert them into named attributes for * uniform processing *) @@ -2658,7 +2664,7 @@ and makeVarInfoCabs ~(isformal: bool) ~(isglobal: bool) (ldecl : location) - (bt, sto, inline, attrs) + (bt, sto, inline, threadlocal, attrs) (n,ndt,a) : varinfo = let vtype, nattr = @@ -2681,6 +2687,7 @@ and makeVarInfoCabs vi.vstorage <- sto; vi.vattr <- nattr; vi.vdecl <- ldecl; + vi.vthreadlocal <- threadlocal; if false then ignore (E.log "Created varinfo %s : %a\n" vi.vname d_type vi.vtype); @@ -3109,7 +3116,7 @@ and isVariableSizedArray (dt: A.decl_type): (A.decl_type * chunk * exp list) opt None and doOnlyType (specs: A.spec_elem list) (dt: A.decl_type) : typ = - let bt',sto,inl,attrs = doSpecList "" specs in + let bt',sto,inl,thrl,attrs = doSpecList "" specs in if sto <> NoStorage || inl then E.s (error "Storage or inline specifier in type only"); let tres, nattr = doType AttrType bt' (A.PARENTYPE(attrs, dt, [])) in @@ -3136,7 +3143,7 @@ and makeCompType (isstruct: bool) [] -> "" | ((n, _, _, _), _) :: _ -> n in - let bt, sto, inl, attrs = doSpecList sugg s in + let bt, sto, inl, thrl, attrs = doSpecList sugg s in (* Do the fields *) let makeFieldInfo (((n,ndt,a,cloc) : A.name), (widtho : A.expression option)) @@ -3561,10 +3568,20 @@ and doExp (asconst: bool) (* This expression is used as a constant *) * the value. But L'abc' has type wchar, and so is equivalent to * L'c'). But gcc allows L'abc', so I'll leave this here in case * I'm missing some architecture dependent behavior. *) - let value = reduce_multichar !wcharType char_list in - let result = kinteger64 !wcharKind value in + let value = reduce_multichar !wcharType char_list in + let result = kinteger64 !wcharKind value in finishExp empty result (typeOf result) + | A.CONST_CHAR16 char_list -> + let value = reduce_multichar !char16Type char_list in + let result = kinteger64 !char16Kind value in + finishExp empty result (typeOf result) + + | A.CONST_CHAR32 char_list -> + let value = reduce_multichar !char32Type char_list in + let result = kinteger64 !char32Kind value in + finishExp empty result (typeOf result) + | A.CONST_FLOAT str -> begin (* Maybe it ends in U or UL. Strip those *) let l = String.length str in @@ -3770,8 +3787,8 @@ and doExp (asconst: bool) (* This expression is used as a constant *) if !scopes == [] then begin (* This is a global. Mark the new vars as static *) let spec_res' = - let t, sto, inl, attrs = spec_res in - t, Static, inl, attrs + let t, sto, inl, thrl, attrs = spec_res in + t, Static, inl, thrl, attrs in ignore (createGlobal spec_res' ((newvar, dt', [], cabslu), ie')); @@ -5529,7 +5546,7 @@ and doInit (* Create and add to the file (if not already added) a global. Return the * varinfo *) -and createGlobal (specs : (typ * storage * bool * A.attribute list)) +and createGlobal (specs : (typ * storage * bool * bool * A.attribute list)) (((n,ndt,a,cloc), inite) : A.init_name) : varinfo = try if debugGlobal then @@ -5540,6 +5557,7 @@ and createGlobal (specs : (typ * storage * bool * A.attribute list)) (* Add the variable to the environment before doing the initializer * because it might refer to the variable itself *) if isFunctionType vi.vtype then begin + if vi.vthreadlocal then E.s (error "Invalid storage class '_Thread_local' for function %s" vi.vname); if inite != A.NO_INIT then E.s (error "Function declaration with initializer (%s)" vi.vname); @@ -5642,7 +5660,7 @@ and createGlobal (specs : (typ * storage * bool * A.attribute list)) *) (* Must catch the Static local variables. Make them global *) -and createLocal ?allow_var_decl:(allow_var_decl=true) ((_, sto, _, _) as specs) +and createLocal ?allow_var_decl:(allow_var_decl=true) ((_, sto, _, _, _) as specs) ((((n, ndt, a, cloc) : A.name), (inite: A.init_expression)) as init_name) : chunk = @@ -5812,7 +5830,7 @@ and doDecl (isglobal: bool) : A.definition -> chunk = function let doOneDeclarator (acc: chunk) (name: init_name) = let (n,ndt,a,l),_ = name in if isglobal then begin - let bt,_,_,attrs = spec_res in + let bt,_,_,_,attrs = spec_res in let vtype, nattr = doType (AttrName false) bt (A.PARENTYPE(attrs, ndt, a)) in (match filterAttributes "alias" nattr with @@ -5939,7 +5957,7 @@ and doDecl (isglobal: bool) : A.definition -> chunk = function (* Fix the NAME and the STORAGE *) let _ = - let bt,sto,inl,attrs = doSpecList n specs in + let bt,sto,inl,thrl,attrs = doSpecList n specs in !currentFunctionFDEC.svar.vinline <- inl; let ftyp, funattr = @@ -6054,8 +6072,7 @@ and doDecl (isglobal: bool) : A.definition -> chunk = function end in let fmlocs = (match dt with PROTO(_, fml, _) -> fml | _ -> []) in - let formals = doFormals (argsToList formals_t) fmlocs in - + let formals = doFormals (argsToList formals_t) fmlocs in (* Recreate the type based on the formals. *) let ftype = TFun(returnType, Some (Util.list_map (fun f -> (f.vname, @@ -6356,7 +6373,7 @@ and doDecl (isglobal: bool) : A.definition -> chunk = function and doTypedef ((specs, nl): A.name_group) = try (* Do the specifiers exactly once *) - let bt, sto, inl, attrs = doSpecList (suggestAnonName nl) specs in + let bt, sto, inl, thrl, attrs = doSpecList (suggestAnonName nl) specs in if sto <> NoStorage || inl then E.s (error "Storage or inline specifier not allowed in typedef"); let createTypedef ((n,ndt,a,loc) : A.name) = @@ -6400,7 +6417,7 @@ and doTypedef ((specs, nl): A.name_group) = and doOnlyTypedef (specs: A.spec_elem list) : unit = try - let bt, sto, inl, attrs = doSpecList "" specs in + let bt, sto, inl, thrl, attrs = doSpecList "" specs in if sto <> NoStorage || inl then E.s (error "Storage or inline specifier not allowed in typedef"); let restyp, nattr = doType AttrType bt (A.PARENTYPE(attrs, @@ -6703,7 +6720,7 @@ and doStatement (s : A.statement) : chunk = (* Make a temporary variable, avoiding generation of VarDecl if possible *) (* as this is unsupported (see below) *) let vchunk = createLocal ~allow_var_decl:false - (!upointType, NoStorage, false, []) + (!upointType, NoStorage, false, false, []) (("__compgoto", A.JUSTBASE, [], loc), A.NO_INIT) in if not (isEmpty vchunk) then diff --git a/src/frontc/cabsvisit.ml b/src/frontc/cabsvisit.ml index ce3c99583..b4369dd34 100644 --- a/src/frontc/cabsvisit.ml +++ b/src/frontc/cabsvisit.ml @@ -220,7 +220,7 @@ and childrenTypeSpecifier vis ts = and childrenSpecElem (vis: cabsVisitor) (se: spec_elem) : spec_elem = match se with - SpecTypedef | SpecInline | SpecStorage _ | SpecPattern _ -> se + SpecTypedef | SpecInline | SpecStorage _ | SpecPattern _ | SpecThreadLocal-> se | SpecCV _ -> se (* cop out *) | SpecFun _ -> se | SpecAttr a -> begin diff --git a/src/frontc/clexer.mll b/src/frontc/clexer.mll index ff8dfc1b6..b20fe2a82 100644 --- a/src/frontc/clexer.mll +++ b/src/frontc/clexer.mll @@ -466,6 +466,7 @@ let floatnum = (decfloat | hexfloat) floatsuffix? let complexnum = (decfloat | hexfloat) ((['i' 'I'] floatsuffix) | (floatsuffix? ['i' 'I'])) +let strprefix = "u8" | "L" | "u" | "U" let blank = [' ' '\t' '\012' '\r']+ let escape = '\\' _ @@ -516,6 +517,8 @@ rule initial = | "_Pragma" { PRAGMA (currentLoc ()) } | '\'' { CST_CHAR (chr lexbuf, currentLoc ())} | "L'" { CST_WCHAR (chr lexbuf, currentLoc ()) } +| "u'" {CST_CHAR16 (chr lexbuf, currentLoc ())} +| "U'" {CST_CHAR32 (chr lexbuf, currentLoc ())} | '"' { addLexeme lexbuf; (* '"' *) (* matth: BUG: this could be either a regular string or a wide string. * e.g. if it's the "world" in @@ -533,6 +536,9 @@ rule initial = raise (InternalError ("wide string: " ^ Printexc.to_string e))} +(* | "u\"" {try CST_STRING16(str lexbuf, currentLoc ()) + with e -> + raise (InternalError ("wide string: " ^ Printexc.to_string e))} *) | floatnum {CST_FLOAT (Lexing.lexeme lexbuf, currentLoc ())} | complexnum {CST_COMPLEX (Lexing.lexeme lexbuf, currentLoc ())} | hexnum {CST_INT (Lexing.lexeme lexbuf, currentLoc ())} @@ -699,6 +705,9 @@ and str = parse | universal_escape {addLexeme lexbuf; lex_universal_escape str lexbuf} | _ {addLexeme lexbuf; lex_unescaped str lexbuf} +and u8_str = parse +"u8" {} + and chr = parse '\'' {[]} | hex_escape {lex_hex_escape chr lexbuf} diff --git a/src/frontc/cparser.mly b/src/frontc/cparser.mly index 45a392b18..470327d5a 100644 --- a/src/frontc/cparser.mly +++ b/src/frontc/cparser.mly @@ -243,7 +243,7 @@ let transformOffsetOf (speclist, dtype) member = %token IDENT %token QUALIFIER %token CST_CHAR -%token CST_WCHAR +%token CST_WCHAR CST_CHAR16 CST_CHAR32 %token CST_INT %token CST_FLOAT %token CST_COMPLEX @@ -252,7 +252,7 @@ let transformOffsetOf (speclist, dtype) member = /* Each character is its own list element, and the terminating nul is not included in this list. */ %token CST_STRING -%token CST_WSTRING +%token CST_WSTRING CST_STRING16 %token EOF %token CHAR INT BOOL DOUBLE FLOAT VOID INT64 INT32 @@ -698,6 +698,8 @@ constant: | CST_COMPLEX {CONST_COMPLEX (fst $1), snd $1} | CST_CHAR {CONST_CHAR (fst $1), snd $1} | CST_WCHAR {CONST_WCHAR (fst $1), snd $1} +| CST_CHAR16 {CONST_CHAR16 (fst $1), snd $1} +| CST_CHAR32 {CONST_CHAR32 (fst $1), snd $1} | string_constant {CONST_STRING (fst $1), snd $1} | wstring_list {CONST_WSTRING (fst $1), snd $1} ; @@ -956,7 +958,7 @@ decl_spec_list: /* ISO 6.7 */ | STATIC decl_spec_list_opt { SpecStorage STATIC :: $2, $1 } | AUTO decl_spec_list_opt { SpecStorage AUTO :: $2, $1 } | REGISTER decl_spec_list_opt { SpecStorage REGISTER :: $2, $1} -| THREADLOCAL decl_spec_list_opt { SpecStorage THREADLOCAL :: $2, $1} +| THREADLOCAL decl_spec_list_opt { SpecThreadLocal :: $2, $1} /* ISO 6.7.2 */ | type_spec decl_spec_list_opt_no_named { SpecType (fst $1) :: $2, snd $1 } /* ISO 6.7.4 */ diff --git a/src/machdep-ml.c.in b/src/machdep-ml.c.in index 91f5a5c94..ed74deb82 100644 --- a/src/machdep-ml.c.in +++ b/src/machdep-ml.c.in @@ -287,7 +287,7 @@ int main(int argc, char **argv) "alignof_enum=%d float=%d,%d double=%d,%d long_double=%d,%d float128=%d,%d " "float_complex=%d,%d double_complex=%d,%d long_double_complex=%d,%d complex128=%d,%d " "void=%d bool=%d,%d fun=%d,%d alignof_string=%d max_alignment=%d size_t=%s " - "wchar_t=%s char_signed=%s const_string_literals=%s " + "wchar_t=%s char16_t=%s char32_t=%s char_signed=%s const_string_literals=%s " "big_endian=%s __thread_is_keyword=%s __builtin_va_list=%s " "underscore_name=%s\n", (int)sizeof(short), alignof_short, (int)sizeof(int), alignof_int, @@ -299,7 +299,7 @@ int main(int argc, char **argv) (int)sizeof(long double _Complex), alignof_longdoublecomplex, (int)sizeof(__complex128), alignof_complex128, (int)sizeof(void), (int)sizeof(bool), alignof_bool, sizeof_fun, alignof_fun, alignof_str, alignof_aligned, - underscore(TYPE_SIZE_T), underscore(TYPE_WCHAR_T), + underscore(TYPE_SIZE_T), underscore(TYPE_WCHAR_T), underscore(TYPE_CHAR16_T), char_is_unsigned ? "false" : "true", CONST_STRING_LITERALS, little_endian ? "false" : "true", THREAD_IS_KEYWORD, HAVE_BUILTIN_VA_LIST, UNDERSCORE_NAME); @@ -332,6 +332,8 @@ int main(int argc, char **argv) printf("\t sizeof_fun = %d;\n", (int)sizeof_fun); printf("\t size_t = \"%s\";\n", TYPE_SIZE_T); printf("\t wchar_t = \"%s\";\n", TYPE_WCHAR_T); + printf("\t char16_t = \"%s\";\n", TYPE_CHAR16_T); + printf("\t char32_t = \"%s\";\n", TYPE_CHAR32_T); printf("\t alignof_short = %d;\n", alignof_short); printf("\t alignof_int = %d;\n", alignof_int); printf("\t alignof_bool = %d;\n", alignof_bool); diff --git a/src/machdepenv.ml b/src/machdepenv.ml index bf2731248..17590eae4 100644 --- a/src/machdepenv.ml +++ b/src/machdepenv.ml @@ -92,6 +92,8 @@ let modelParse (s:string) : mach = alignof_aligned = getInt entries "max_alignment"; size_t = respace (getNthString 0 entries "size_t"); wchar_t = respace (getNthString 0 entries "wchar_t"); + char16_t = respace (getNthString 0 entries "char16_t"); + char32_t = respace (getNthString 0 entries "char32_t"); char_is_unsigned = not (getBool entries "char_signed"); const_string_literals = getBool entries "const_string_literals"; little_endian = not (getBool entries "big_endian"); From 2621ed17733cd4a90b706bddd4d0527160b4aeab Mon Sep 17 00:00:00 2001 From: Baris Coslu Date: Wed, 29 Jul 2020 19:42:13 +0300 Subject: [PATCH 03/16] u8 string literal prefix --- src/frontc/clexer.mll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontc/clexer.mll b/src/frontc/clexer.mll index b20fe2a82..951276869 100644 --- a/src/frontc/clexer.mll +++ b/src/frontc/clexer.mll @@ -519,7 +519,7 @@ rule initial = | "L'" { CST_WCHAR (chr lexbuf, currentLoc ()) } | "u'" {CST_CHAR16 (chr lexbuf, currentLoc ())} | "U'" {CST_CHAR32 (chr lexbuf, currentLoc ())} -| '"' { addLexeme lexbuf; (* '"' *) +| '"' | "u8\"" { addLexeme lexbuf; (* '"' *) (* matth: BUG: this could be either a regular string or a wide string. * e.g. if it's the "world" in * L"Hello, " "world" @@ -538,7 +538,7 @@ rule initial = Printexc.to_string e))} (* | "u\"" {try CST_STRING16(str lexbuf, currentLoc ()) with e -> - raise (InternalError ("wide string: " ^ Printexc.to_string e))} *) + raise (InternalError ("wide string: " ^ Printexc.to_string e))} *) | floatnum {CST_FLOAT (Lexing.lexeme lexbuf, currentLoc ())} | complexnum {CST_COMPLEX (Lexing.lexeme lexbuf, currentLoc ())} | hexnum {CST_INT (Lexing.lexeme lexbuf, currentLoc ())} From 3919a323c81801796e2071b69701faa54e48caba Mon Sep 17 00:00:00 2001 From: Baris Coslu Date: Sun, 16 Aug 2020 18:26:41 +0300 Subject: [PATCH 04/16] _Thread_local and wide strings --- src/cil.ml | 24 +++++++++++++----------- src/cil.mli | 4 +++- src/ext/llvm/llvmgen.ml | 2 +- src/frontc/cabs.ml | 8 ++++---- src/frontc/cabs2cil.ml | 31 +++++++++++++++---------------- src/frontc/clexer.mll | 7 +++++-- src/frontc/cparser.mly | 23 ++++++++++++++++++----- src/frontc/cprint.ml | 17 +++++++++++++---- 8 files changed, 72 insertions(+), 44 deletions(-) diff --git a/src/cil.ml b/src/cil.ml index 3c1e40d1c..f5973acc7 100755 --- a/src/cil.ml +++ b/src/cil.ml @@ -542,6 +542,7 @@ and exp = * [TArray(T)] produces an expression of type * [TPtr(T)]. *) +and wstring_type = | Wchar_t | Char16_t | Char32_t (** Literal constants *) and constant = @@ -551,8 +552,8 @@ and constant = * {!Cil.integer} or {!Cil.kinteger} to create these. Watch * out for integers that cannot be represented on 64 bits. * OCAML does not give Overflow exceptions. *) - | CStr of string (** String constant (of pointer type) *) - | CWStr of int64 list (** Wide string constant (of type "wchar_t *") *) + | CStr of string(** String constant (of pointer type) *) + | CWStr of int64 list * wstring_type (** Wide string constant (of type "wchar_t *") *) | CChr of char (** Character constant. This has type int, so use * charConstToInt to read the value in case * sign-extension is needed. *) @@ -1785,8 +1786,9 @@ let d_const () c = ) | CStr(s) -> text ("\"" ^ escape_string s ^ "\"") - | CWStr(s) -> + | CWStr(s, st) -> (* text ("L\"" ^ escape_string s ^ "\"") *) + let prefix = match st with Wchar_t -> "L" | Char16_t -> "u" | Char32_t -> "U" in (List.fold_left (fun acc elt -> acc ++ if (elt >= Int64.zero && @@ -1795,7 +1797,7 @@ let d_const () c = else ( text (Printf.sprintf "\\x%LX\"" elt) ++ break ++ (text "\"")) - ) (text "L\"") s ) ++ text "\"" + ) (text (prefix ^ "\"")) s ) ++ text "\"" (* we cannot print L"\xabcd" "feedme" as L"\xabcdfeedme" -- * the former has 7 wide characters and the later has 3. *) @@ -1940,7 +1942,7 @@ let rec typeOf (e: exp) : typ = * have SizeOfStr for that *) | Const(CStr s) -> !stringLiteralType - | Const(CWStr s) -> TPtr(!wcharType,[]) + | Const(CWStr (s,st)) -> TPtr((match st with Wchar_t -> !wcharType | Char16_t -> !char16Type | Char32_t -> !char32Type), []) | Const(CReal (_, fk, _)) -> TFloat(fk, []) @@ -4815,23 +4817,23 @@ class plainCilPrinterClass = let d_plainconst () c = match c with CInt64(i, ik, so) -> - let fmt = if isSigned ik then "%d" else "%x" in + let fmt = if isSigned ik then "%d" else "%x" in dprintf "Int64(%s,%a,%s)" (Int64.format fmt i) d_ikind ik (match so with Some s -> s | _ -> "None") - | CStr(s) -> + | CStr(s) -> text ("CStr(\"" ^ escape_string s ^ "\")") - | CWStr(s) -> + | CWStr(s,_) -> dprintf "CWStr(%a)" d_const c - | CChr(c) -> text ("CChr('" ^ escape_char c ^ "')") - | CReal(f, fk, so) -> + | CChr(c) -> text ("CChr('" ^ escape_char c ^ "')") + | CReal(f, fk, so) -> dprintf "CReal(%f, %a, %s)" f d_fkind fk (match so with Some s -> s | _ -> "None") - | CEnum(_, s, _) -> text s + | CEnum(_, s, _) -> text s in text "Const(" ++ d_plainconst () c ++ text ")" diff --git a/src/cil.mli b/src/cil.mli index d913a5e70..213309a4a 100644 --- a/src/cil.mli +++ b/src/cil.mli @@ -638,6 +638,8 @@ and exp = (** {b Constants.} *) +and wstring_type = | Wchar_t | Char16_t | Char32_t + (** Literal constants *) and constant = | CInt64 of int64 * ikind * string option @@ -652,7 +654,7 @@ and constant = * only case when you would like a string literal to have an array type * is when it is an argument to sizeof. In that case you should use * SizeOfStr. *) - | CWStr of int64 list + | CWStr of int64 list * wstring_type (** Wide character string constant. Note that the local interpretation * of such a literal depends on {!Cil.wcharType} and {!Cil.wcharKind}. * Such a constant has type pointer to {!Cil.wcharType}. The diff --git a/src/ext/llvm/llvmgen.ml b/src/ext/llvm/llvmgen.ml index 99c51fed8..8c81ee998 100644 --- a/src/ext/llvm/llvmgen.ml +++ b/src/ext/llvm/llvmgen.ml @@ -590,7 +590,7 @@ class llvmGeneratorClass : llvmGenerator = object (self) match c with | CInt64 (i, ik, _) -> LInt (i, ik) | CStr s -> LGetelementptr [ LGlobal (self#addString s); lzerop; lzerop ] - | CWStr ws -> LGetelementptr [ LGlobal (self#addWString ws); lzerop; lzerop ] + | CWStr (ws,_) -> LGetelementptr [ LGlobal (self#addWString ws); lzerop; lzerop ] | CChr c -> LInt (Int64.of_int (Char.code c), IInt) | CReal (f, fk, _) -> LFloat (f, fk) | CEnum (e, _, ei) -> LInt (intConstValue e, ei.ekind) diff --git a/src/frontc/cabs.ml b/src/frontc/cabs.ml index 925dfb5f1..fc1768255 100644 --- a/src/frontc/cabs.ml +++ b/src/frontc/cabs.ml @@ -289,17 +289,17 @@ and constant = | CONST_FLOAT of string (* the textual representaton *) | CONST_COMPLEX of string (* the textual representation *) | CONST_CHAR of int64 list - | CONST_WCHAR of int64 list - | CONST_CHAR16 of int64 list - | CONST_CHAR32 of int64 list + | CONST_WCHAR of int64 list * wchar_type | CONST_STRING of string - | CONST_WSTRING of int64 list + | CONST_WSTRING of int64 list * wchar_type (* ww: wstrings are stored as an int64 list at this point because * we might need to feed the wide characters piece-wise into an * array initializer (e.g., wchar_t foo[] = L"E\xabcd";). If that * doesn't happen we will convert it to an (escaped) string before * passing it to Cil. *) +and wchar_type = WCHAR_T | CHAR16_T | CHAR32_T + and init_expression = | NO_INIT | SINGLE_INIT of expression diff --git a/src/frontc/cabs2cil.ml b/src/frontc/cabs2cil.ml index ea9c6a849..3da282c33 100644 --- a/src/frontc/cabs2cil.ml +++ b/src/frontc/cabs2cil.ml @@ -1823,6 +1823,8 @@ let makeGlobalVarinfo (isadef: bool) (vi: varinfo) : varinfo * bool = (* This may throw an exception Not_found *) let oldvi, oldloc = lookupGlobalVar lookupname in + if oldvi.vthreadlocal <> vi.vthreadlocal then + ignore (E.log "_Thread_local appears in a declaration of '%s' but is not present in every declaration.\n" vi.vname); if debug then ignore (E.log " %s already in the env at loc %a\n" vi.vname d_loc oldloc); @@ -3532,8 +3534,9 @@ and doExp (asconst: bool) (* This expression is used as a constant *) (TPtr(wchar_t, [])) *) - | A.CONST_WSTRING (ws: int64 list) -> - let res = Const(CWStr ((* intlist_to_wstring *) ws)) in + | A.CONST_WSTRING (ws, wst) -> + let cil_wst = match wst with WCHAR_T -> Wchar_t | CHAR16_T -> Char16_t | CHAR32_T -> Char32_t in + let res = Const(CWStr ((* intlist_to_wstring *) ws, cil_wst)) in finishExp empty res (typeOf res) | A.CONST_STRING s -> @@ -3560,7 +3563,7 @@ and doExp (asconst: bool) (* This expression is used as a constant *) let a, b = (interpret_character_constant char_list) in finishExp empty (Const a) b - | A.CONST_WCHAR char_list -> + | A.CONST_WCHAR (char_list, wct) -> (* matth: I can't see a reason for a list of more than one char * here, since the kinteger64 below will take only the lower 16 * bits of value. ('abc' makes sense, because CHAR constants have @@ -3568,18 +3571,14 @@ and doExp (asconst: bool) (* This expression is used as a constant *) * the value. But L'abc' has type wchar, and so is equivalent to * L'c'). But gcc allows L'abc', so I'll leave this here in case * I'm missing some architecture dependent behavior. *) - let value = reduce_multichar !wcharType char_list in - let result = kinteger64 !wcharKind value in - finishExp empty result (typeOf result) - | A.CONST_CHAR16 char_list -> - let value = reduce_multichar !char16Type char_list in - let result = kinteger64 !char16Kind value in - finishExp empty result (typeOf result) - - | A.CONST_CHAR32 char_list -> - let value = reduce_multichar !char32Type char_list in - let result = kinteger64 !char32Kind value in + let wcType, wcKind = match wct with + | WCHAR_T -> !wcharType, !wcharKind + | CHAR16_T -> !char16Type, !char16Kind + | CHAR32_T -> !char32Type, !char32Kind + in + let value = reduce_multichar wcType char_list in + let result = kinteger64 !wcharKind value in finishExp empty result (typeOf result) | A.CONST_FLOAT str -> begin @@ -5256,11 +5255,11 @@ and doInit * important. *) | TArray(bt, leno, _), (A.NEXT_INIT, - (A.SINGLE_INIT(A.CONSTANT (A.CONST_WSTRING s)) | + (A.SINGLE_INIT(A.CONSTANT (A.CONST_WSTRING (s,_))) | A.COMPOUND_INIT [(A.NEXT_INIT, A.SINGLE_INIT(A.CONSTANT - (A.CONST_WSTRING s)))])) :: restil + (A.CONST_WSTRING (s, _))))])) :: restil when(let bt' = unrollType bt in match bt' with (* compare bt to wchar_t, ignoring signed vs. unsigned *) diff --git a/src/frontc/clexer.mll b/src/frontc/clexer.mll index 951276869..f4620187d 100644 --- a/src/frontc/clexer.mll +++ b/src/frontc/clexer.mll @@ -536,9 +536,12 @@ rule initial = raise (InternalError ("wide string: " ^ Printexc.to_string e))} -(* | "u\"" {try CST_STRING16(str lexbuf, currentLoc ()) +| "u\"" {try CST_STRING16(str lexbuf, currentLoc ()) with e -> - raise (InternalError ("wide string: " ^ Printexc.to_string e))} *) + raise (InternalError ("wide string: " ^ Printexc.to_string e))} +| "U\"" {try CST_STRING32(str lexbuf, currentLoc ()) + with e -> + raise (InternalError ("wide string: " ^ Printexc.to_string e))} | floatnum {CST_FLOAT (Lexing.lexeme lexbuf, currentLoc ())} | complexnum {CST_COMPLEX (Lexing.lexeme lexbuf, currentLoc ())} | hexnum {CST_INT (Lexing.lexeme lexbuf, currentLoc ())} diff --git a/src/frontc/cparser.mly b/src/frontc/cparser.mly index 470327d5a..0bda9999c 100644 --- a/src/frontc/cparser.mly +++ b/src/frontc/cparser.mly @@ -252,7 +252,7 @@ let transformOffsetOf (speclist, dtype) member = /* Each character is its own list element, and the terminating nul is not included in this list. */ %token CST_STRING -%token CST_WSTRING CST_STRING16 +%token CST_WSTRING CST_STRING16 CST_STRING32 %token EOF %token CHAR INT BOOL DOUBLE FLOAT VOID INT64 INT32 @@ -697,11 +697,13 @@ constant: | CST_FLOAT {CONST_FLOAT (fst $1), snd $1} | CST_COMPLEX {CONST_COMPLEX (fst $1), snd $1} | CST_CHAR {CONST_CHAR (fst $1), snd $1} -| CST_WCHAR {CONST_WCHAR (fst $1), snd $1} -| CST_CHAR16 {CONST_CHAR16 (fst $1), snd $1} -| CST_CHAR32 {CONST_CHAR32 (fst $1), snd $1} +| CST_WCHAR {CONST_WCHAR (fst $1, WCHAR_T), snd $1} +| CST_CHAR16 {CONST_WCHAR (fst $1, CHAR16_T), snd $1} +| CST_CHAR32 {CONST_WCHAR (fst $1, CHAR32_T), snd $1} | string_constant {CONST_STRING (fst $1), snd $1} -| wstring_list {CONST_WSTRING (fst $1), snd $1} +| wstring_list {CONST_WSTRING (fst $1, WCHAR_T), snd $1} +| string16_list {CONST_WSTRING (fst $1, CHAR16_T), snd $1} +| string32_list {CONST_WSTRING (fst $1, CHAR32_T), snd $1} ; string_constant: @@ -739,9 +741,20 @@ wstring_list: CST_WSTRING { $1 } | wstring_list one_string { (fst $1) @ (fst $2), snd $1 } | wstring_list CST_WSTRING { (fst $1) @ (fst $2), snd $1 } +| one_string wstring_list { (fst $1) @ (fst $2), snd $1 } /* Only the first string in the list needs an L, so L"a" "b" is the same * as L"ab" or L"a" L"b". */ +string16_list: + CST_STRING16 { $1 } +| string16_list one_string { (fst $1) @ (fst $2), snd $1 } +| string16_list CST_STRING16 { (fst $1) @ (fst $2), snd $1 } + +string32_list: + CST_STRING32 { $1 } +| string32_list one_string { (fst $1) @ (fst $2), snd $1 } +| string32_list CST_STRING32 { (fst $1) @ (fst $2), snd $1 } + one_string: CST_STRING {$1} | FUNCTION__ {(Cabshelper.explodeStringToInts diff --git a/src/frontc/cprint.ml b/src/frontc/cprint.ml index c47e0ebe8..93e6c440b 100644 --- a/src/frontc/cprint.ml +++ b/src/frontc/cprint.ml @@ -133,8 +133,9 @@ let print_commas nl fct lst = let print_string (s:string) = print ("\"" ^ escape_string s ^ "\"") -let print_wstring (s: int64 list ) = - print ("L\"" ^ escape_wstring s ^ "\"") +let print_wstring (s: int64 list ) (wst: Cabs.wchar_type) = + let prefix = match wst with WCHAR_T -> "L" | CHAR16_T -> "u" | CHAR32_T -> "U" in + print (prefix ^ "\"" ^ escape_wstring s ^ "\"") (* ** Base Type Printing @@ -152,6 +153,13 @@ let rec print_specifiers (specs: spec_elem list) = | STATIC -> "static" | EXTERN -> "extern" | REGISTER -> "register") + | SpecThreadLocal -> printu "_Thread_local" + | SpecFun sf -> + printu (match sf with + INLINE -> "inline" + | VIRTUAL -> "virtual" + | EXPLICIT -> "explicit" + | NORETURN -> "_Noreturn") | SpecCV cv -> printu (match cv with | CV_CONST -> "const" @@ -177,6 +185,7 @@ and print_type_spec = function | Tint128 -> print "__int128 " | Tfloat -> print "float " | Tfloat128 -> print "__float128" + | Tcomplex128 -> print "__complex128" | Tdouble -> print "double " | Tsigned -> printu "signed" | Tunsigned -> print "unsigned " @@ -517,9 +526,9 @@ and print_expression_level (lvl: int) (exp : expression) = | CONST_FLOAT r -> print r | CONST_COMPLEX r -> print r | CONST_CHAR c -> print ("'" ^ escape_wstring c ^ "'") - | CONST_WCHAR c -> print ("L'" ^ escape_wstring c ^ "'") + | CONST_WCHAR (c, wct) -> print ("L'" ^ escape_wstring c ^ "'") (*TODO*) | CONST_STRING s -> print_string s - | CONST_WSTRING ws -> print_wstring ws) + | CONST_WSTRING (ws, wst) -> print_wstring ws wst) | VARIABLE name -> comprint "variable"; print name From 1df5df068e60d72ee1b819d0bbd819a29309d961 Mon Sep 17 00:00:00 2001 From: Baris Coslu Date: Thu, 20 Aug 2020 16:34:42 +0300 Subject: [PATCH 05/16] _Alignof, _Alignas and wide string fix --- src/cil.ml | 69 +++++++++++++++++--- src/cil.mli | 7 +- src/frontc/cabs.ml | 4 +- src/frontc/cabs2cil.ml | 15 +++++ src/frontc/cabsvisit.ml | 7 ++ src/frontc/clexer.mll | 15 +++-- src/frontc/cparser.mly | 137 ++++++++++++++++++++++++++++------------ 7 files changed, 197 insertions(+), 57 deletions(-) diff --git a/src/cil.ml b/src/cil.ml index f5973acc7..bd20a642f 100755 --- a/src/cil.ml +++ b/src/cil.ml @@ -328,6 +328,9 @@ and attrparam = | AAlignOf of typ | AAlignOfE of attrparam | AAlignOfS of typsig + | AAlignOf_C11 of typ (* We differentiate between the C11 _Alignof and the GCC __alignof__ *) + | AAlignOfE_C11 of attrparam + | AAlignOfS_C11 of typsig | AUnOp of unop * attrparam | ABinOp of binop * attrparam * attrparam | ADot of attrparam * string (** a.foo **) @@ -513,6 +516,8 @@ and exp = | AlignOf of typ (** Has [unsigned int] type *) | AlignOfE of exp + | AlignOf_C11 of typ (** Has [unsigned int] type *) + | AlignOfE_C11 of exp | UnOp of unop * exp * typ (** Unary operation. Includes the type of the result *) @@ -1863,7 +1868,7 @@ let getParenthLevel (e: exp) = | Lval(Mem _ , _) -> derefStarLevel (* 20 *) | Lval(Var _, (Field _|Index _)) -> indexLevel (* 20 *) | SizeOf _ | SizeOfE _ | SizeOfStr _ -> 20 - | AlignOf _ | AlignOfE _ -> 20 + | AlignOf _ | AlignOfE _ | AlignOf_C11 _ | AlignOfE_C11 _ -> 20 | Lval(Var _, NoOffset) -> 0 (* Plain variables *) | Const _ -> 0 (* Constants *) @@ -1874,7 +1879,7 @@ let getParenthLevelAttrParam (a: attrparam) = match a with AInt _ | AStr _ | ACons _ -> 0 | ASizeOf _ | ASizeOfE _ | ASizeOfS _ -> 20 - | AAlignOf _ | AAlignOfE _ | AAlignOfS _ -> 20 + | AAlignOf _ | AAlignOfE _ | AAlignOfS _ | AAlignOf_C11 _ | AAlignOfE_C11 _ | AAlignOfS_C11 _ -> 20 | AUnOp (uo, _) -> getParenthLevel (UnOp(uo, zero, intType)) | ABinOp (bo, _, _) -> getParenthLevel (BinOp(bo, zero, zero, intType)) | AAddrOf _ -> 30 @@ -1951,7 +1956,7 @@ let rec typeOf (e: exp) : typ = | Imag e -> typeOfRealAndImagComponents @@ typeOf e | Lval(lv) -> typeOfLval lv | SizeOf _ | SizeOfE _ | SizeOfStr _ -> !typeOfSizeOf - | AlignOf _ | AlignOfE _ -> !typeOfSizeOf + | AlignOf _ | AlignOfE _ | AlignOf_C11 _ | AlignOfE_C11 _ -> !typeOfSizeOf | UnOp (_, _, t) | BinOp (_, _, _, t) | Question (_, _, _, t) @@ -2253,7 +2258,7 @@ let rec alignOf_int t = | TFun _ as t -> raise (SizeOfError ("function", t)) | TVoid _ as t -> raise (SizeOfError ("void", t)) in - match filterAttributes "aligned" (typeAttrs t) with + match filterAttributes "aligned" (typeAttrs t) @ filterAttributes "alignas" (typeAttrs t) with [] -> (* no __aligned__ attribute, so get the default alignment *) alignOfType () @@ -2266,7 +2271,15 @@ let rec alignOf_int t = ignore (warn "ignoring duplicate align attributes on %a" (!pd_type) t); match intOfAttrparam a with - Some n -> n + | Some 0 -> alignOfType () + | Some n -> + let is_power_of_two n = + let log2 = (log10 (float_of_int n)) /. (log10 2.) in + ceil log2 = floor log2 + in + if not (is_power_of_two n) then + alignOfType (ignore(warn "Invalid alignment value specified by attribute %a\n" (!pd_attr) at)) + else n | None -> ignore (warn "alignment attribute \"%a\" not understood on %a" (!pd_attr) at (!pd_type) t); @@ -2300,7 +2313,7 @@ and intOfAttrparam (a:attrparam) : int option = | ASizeOf(t) -> let bs = bitsSizeOf t in bs / 8 - | AAlignOf(t) -> + | AAlignOf(t) | AAlignOf_C11(t)-> alignOf_int t | _ -> raise (SizeOfError ("", voidType)) in @@ -2664,7 +2677,8 @@ and constFold (machdep: bool) (e: exp) : exp = end | SizeOfE e when machdep -> constFold machdep (SizeOf (typeOf e)) | SizeOfStr s when machdep -> kinteger !kindOfSizeOf (1 + String.length s) - | AlignOf t when machdep -> kinteger !kindOfSizeOf (alignOf_int t) + | AlignOf t + | AlignOf_C11 t when machdep -> kinteger !kindOfSizeOf (alignOf_int t) | AlignOfE e when machdep -> begin (* The alignment of an expression is not always the alignment of its * type. I know that for strings this is not true *) @@ -2674,6 +2688,15 @@ and constFold (machdep: bool) (e: exp) : exp = (* For an array, it is the alignment of the array ! *) | _ -> constFold machdep (AlignOf (typeOf e)) end + | AlignOfE_C11 e when machdep -> begin + (* The alignment of an expression is not always the alignment of its + * type. I know that for strings this is not true *) + match e with + Const (CStr _) when not !msvcMode -> + kinteger !kindOfSizeOf !M.theMachine.M.alignof_str + (* For an array, it is the alignment of the array ! *) + | _ -> constFold machdep (AlignOf_C11 (typeOf e)) +end | CastE(it, AddrOf (Mem (CastE(TPtr(bt, _), z)), off)) @@ -2826,7 +2849,7 @@ let rec isConstant = function | Lval _ -> false | Real e -> isConstant e | Imag e -> isConstant e - | SizeOf _ | SizeOfE _ | SizeOfStr _ | AlignOf _ | AlignOfE _ -> true + | SizeOf _ | SizeOfE _ | SizeOfStr _ | AlignOf _ | AlignOfE _ | AlignOf_C11 _ | AlignOfE_C11 _ -> true | CastE (_, e) -> isConstant e | AddrOf (Var vi, off) | StartOf (Var vi, off) -> vi.vglob && isConstantOffset off @@ -3518,6 +3541,10 @@ class defaultCilPrinterClass : cilPrinter = object (self) text "__alignof__(" ++ self#pType None () t ++ chr ')' | AlignOfE (e) -> text "__alignof__(" ++ self#pExp () e ++ chr ')' + | AlignOf_C11 (t) -> + text "_Alignof(" ++ self#pType None () t ++ chr ')' + | AlignOfE_C11 (e) -> + text "_Alignof(" ++ self#pExp () e ++ chr ')' | AddrOf(lv) -> text "& " ++ (self#pLvalPrec addrOfLevel () lv) | AddrOfLabel(sref) -> begin @@ -4496,6 +4523,10 @@ class defaultCilPrinterClass : cilPrinter = object (self) | "volatile", [] -> text "volatile", false | "restrict", [] -> text "__restrict", false | "c_noreturn", [] -> text "_Noreturn", false + | "alignas", args -> + text "_Alignas(" + ++ docList (self#pAttrParam ()) () args + ++ text ")", false | "missingproto", [] -> text "/* missing proto */", false | "cdecl", [] when !msvcMode -> text "__cdecl", false | "stdcall", [] when !msvcMode -> text "__stdcall", false @@ -4574,6 +4605,9 @@ class defaultCilPrinterClass : cilPrinter = object (self) | AAlignOfE a -> text "__alignof__(" ++ self#pAttrParam () a ++ text ")" | AAlignOf t -> text "__alignof__(" ++ self#pType None () t ++ text ")" | AAlignOfS ts -> text "__alignof__()" + | AAlignOf_C11 t -> text "_Alignof(" ++ self#pType None () t ++ text ")" + | AAlignOfE_C11 a -> text "_Alignof(" ++ self#pAttrParam () a ++ text ")" + | AAlignOfS_C11 ts -> text "_Alignof()" | AUnOp(u,a1) -> (d_unop () u) ++ chr ' ' ++ (self#pAttrPrec level () a1) @@ -4879,6 +4913,10 @@ class plainCilPrinterClass = text "__alignof__(" ++ self#pType None () t ++ chr ')' | AlignOfE (e) -> text "__alignof__(" ++ self#pExp () e ++ chr ')' + | AlignOf_C11 (t) -> + text "_Alignof(" ++ self#pType None () t ++ chr ')' + | AlignOfE_C11 (e) -> + text "_Alignof(" ++ self#pExp () e ++ chr ')' | Imag e -> text "__imag__(" ++ self#pExp () e ++ chr ')' | Real e -> @@ -5378,6 +5416,12 @@ and childrenExp (vis: cilVisitor) (e: exp) : exp = | AlignOfE e1 -> let e1' = vExp e1 in if e1' != e1 then AlignOfE e1' else e + | AlignOf_C11 t -> + let t' = vTyp t in + if t' != t then AlignOf_C11 t' else e + | AlignOfE_C11 e1 -> + let e1' = vExp e1 in + if e1' != e1 then AlignOfE_C11 e1' else e | Lval lv -> let lv' = vLval lv in if lv' != lv then Lval lv' else e @@ -5726,7 +5770,13 @@ and childrenAttrparam (vis: cilVisitor) (aa: attrparam) : attrparam = | AAlignOfE e -> let e' = fAttrP e in if e' != e then AAlignOfE e' else aa - | ASizeOfS _ | AAlignOfS _ -> + | AAlignOf_C11 t -> + let t' = fTyp t in + if t' != t then AAlignOf_C11 t' else aa + | AAlignOfE_C11 e -> + let e' = fAttrP e in + if e' != e then AAlignOfE_C11 e' else aa + | ASizeOfS _ | AAlignOfS _ | AAlignOfS_C11 _ -> ignore (warn "Visitor inside of a type signature."); aa | AUnOp (uo, e1) -> @@ -6135,6 +6185,7 @@ class typeSigVisitor(typeSigConverter: typ->typsig) = object match ap with | ASizeOf t -> ChangeTo (ASizeOfS (typeSigConverter t)) | AAlignOf t -> ChangeTo (AAlignOfS (typeSigConverter t)) + | AAlignOf_C11 t -> ChangeTo (AAlignOfS_C11 (typeSigConverter t)) | _ -> DoChildren end diff --git a/src/cil.mli b/src/cil.mli index 213309a4a..ac6a7f170 100644 --- a/src/cil.mli +++ b/src/cil.mli @@ -329,6 +329,9 @@ and attrparam = | AAlignOf of typ | AAlignOfE of attrparam | AAlignOfS of typsig + | AAlignOf_C11 of typ (* We differentiate between the C11 _Alignof and the GCC __alignof__ *) + | AAlignOfE_C11 of attrparam + | AAlignOfS_C11 of typsig | AUnOp of unop * attrparam | ABinOp of binop * attrparam * attrparam | ADot of attrparam * string (** a.foo **) @@ -604,7 +607,9 @@ and exp = (** This corresponds to the GCC __alignof_. Has [unsigned int] type *) | AlignOfE of exp - + | AlignOf_C11 of typ + | AlignOfE_C11 of exp + | UnOp of unop * exp * typ (** Unary operation. Includes the type of the result. *) diff --git a/src/frontc/cabs.ml b/src/frontc/cabs.ml index fc1768255..d43d43dd7 100644 --- a/src/frontc/cabs.ml +++ b/src/frontc/cabs.ml @@ -278,6 +278,8 @@ and expression = | TYPE_SIZEOF of specifier * decl_type | EXPR_ALIGNOF of expression | TYPE_ALIGNOF of specifier * decl_type + | EXPR_ALIGNOF_C11 of expression + | TYPE_ALIGNOF_C11 of specifier * decl_type | INDEX of expression * expression | MEMBEROF of expression * string | MEMBEROFPTR of expression * string @@ -298,7 +300,7 @@ and constant = * doesn't happen we will convert it to an (escaped) string before * passing it to Cil. *) -and wchar_type = WCHAR_T | CHAR16_T | CHAR32_T +and wchar_type = WCHAR_T | CHAR16_T | CHAR32_T | CHAR and init_expression = | NO_INIT diff --git a/src/frontc/cabs2cil.ml b/src/frontc/cabs2cil.ml index 3da282c33..f9ef1e61f 100644 --- a/src/frontc/cabs2cil.ml +++ b/src/frontc/cabs2cil.ml @@ -2782,6 +2782,8 @@ and doAttr (a: A.attribute) : attribute list = | A.TYPE_SIZEOF (bt, dt) -> ASizeOf (doOnlyType bt dt) | A.EXPR_ALIGNOF e -> AAlignOfE (ae e) | A.TYPE_ALIGNOF (bt, dt) -> AAlignOf (doOnlyType bt dt) + | A.EXPR_ALIGNOF_C11 e -> AAlignOfE_C11 (ae e) + | A.TYPE_ALIGNOF_C11 (bt, dt) -> AAlignOf_C11 (doOnlyType bt dt) | A.BINARY(A.AND, aa1, aa2) -> ABinOp(LAnd, ae aa1, ae aa2) | A.BINARY(A.OR, aa1, aa2) -> @@ -3751,6 +3753,19 @@ and doExp (asconst: bool) (* This expression is used as a constant *) | _ -> e' in finishExp empty (AlignOfE(e'')) !typeOfSizeOf + | A.TYPE_ALIGNOF_C11 (bt, dt) -> + let typ = doOnlyType bt dt in + finishExp empty (AlignOf_C11(typ)) !typeOfSizeOf + | A.EXPR_ALIGNOF_C11 e -> + let (se, e', t) = doExp false e AExpLeaveArrayFun in + let e'' = + match e' with (* If we are taking the alignof an + * array we must drop the StartOf *) + StartOf(lv) -> Lval(lv) + + | _ -> e' + in + finishExp empty (AlignOfE_C11(e'')) !typeOfSizeOf | A.CAST ((specs, dt), ie) -> let s', dt', ie' = preprocessCast specs dt ie in diff --git a/src/frontc/cabsvisit.ml b/src/frontc/cabsvisit.ml index b4369dd34..846195b4c 100644 --- a/src/frontc/cabsvisit.ml +++ b/src/frontc/cabsvisit.ml @@ -525,6 +525,13 @@ and childrenExpression vis e = let s' = visitCabsSpecifier vis s in let dt' = visitCabsDeclType vis false dt in if s' != s || dt' != dt then TYPE_ALIGNOF (s' ,dt') else e + | EXPR_ALIGNOF_C11 (e1) -> + let e1' = ve e1 in + if e1' != e1 then EXPR_ALIGNOF_C11 (e1') else e + | TYPE_ALIGNOF_C11 (s, dt) -> + let s' = visitCabsSpecifier vis s in + let dt' = visitCabsDeclType vis false dt in + if s' != s || dt' != dt then TYPE_ALIGNOF_C11 (s' ,dt') else e | INDEX (e1, e2) -> let e1' = ve e1 in let e2' = ve e2 in diff --git a/src/frontc/clexer.mll b/src/frontc/clexer.mll index f4620187d..3f183485c 100644 --- a/src/frontc/clexer.mll +++ b/src/frontc/clexer.mll @@ -171,6 +171,8 @@ let init_lexicon _ = IDENT ("_inline", loc)); ("_Noreturn", fun loc -> NORETURN loc); ("_Thread_local", fun loc -> THREADLOCAL loc); + ("_Alignof", fun loc -> ALIGNOFC11 loc); + ("_Alignas", fun loc -> ALIGNAS loc); ("__attribute__", fun loc -> ATTRIBUTE loc); ("__attribute", fun loc -> ATTRIBUTE loc); (* @@ -466,8 +468,6 @@ let floatnum = (decfloat | hexfloat) floatsuffix? let complexnum = (decfloat | hexfloat) ((['i' 'I'] floatsuffix) | (floatsuffix? ['i' 'I'])) -let strprefix = "u8" | "L" | "u" | "U" - let blank = [' ' '\t' '\012' '\r']+ let escape = '\\' _ let hex_escape = '\\' ['x' 'X'] hexdigit+ @@ -519,7 +519,7 @@ rule initial = | "L'" { CST_WCHAR (chr lexbuf, currentLoc ()) } | "u'" {CST_CHAR16 (chr lexbuf, currentLoc ())} | "U'" {CST_CHAR32 (chr lexbuf, currentLoc ())} -| '"' | "u8\"" { addLexeme lexbuf; (* '"' *) +| '"' { addLexeme lexbuf; (* '"' *) (* matth: BUG: this could be either a regular string or a wide string. * e.g. if it's the "world" in * L"Hello, " "world" @@ -530,6 +530,12 @@ rule initial = raise (InternalError ("str: " ^ Printexc.to_string e))} +| "u8\"" { addLexeme lexbuf; (* '"' *) + try CST_U8STRING (str lexbuf, currentLoc ()) + with e -> + raise (InternalError + ("str: " ^ + Printexc.to_string e))} | "L\"" { (* weimer: wchar_t string literal *) try CST_WSTRING(str lexbuf, currentLoc ()) with e -> @@ -708,9 +714,6 @@ and str = parse | universal_escape {addLexeme lexbuf; lex_universal_escape str lexbuf} | _ {addLexeme lexbuf; lex_unescaped str lexbuf} -and u8_str = parse -"u8" {} - and chr = parse '\'' {[]} | hex_escape {lex_hex_escape chr lexbuf} diff --git a/src/frontc/cparser.mly b/src/frontc/cparser.mly index 0bda9999c..3bf15392f 100644 --- a/src/frontc/cparser.mly +++ b/src/frontc/cparser.mly @@ -238,6 +238,19 @@ let transformOffsetOf (speclist, dtype) member = let resultExpr = CAST (sizeofType, SINGLE_INIT addrExpr) in resultExpr +let queue_to_int64_list queue = + List.rev (Queue.fold (fun l e -> List.rev_append e l) [] queue) + +let queue_to_string queue = + let buffer = Buffer.create (Queue.length queue) in + Queue.iter + (List.iter + (fun value -> + let char = int64_to_char value in + Buffer.add_char buffer char)) + queue; + Buffer.contents buffer + %} %token IDENT @@ -252,12 +265,12 @@ let transformOffsetOf (speclist, dtype) member = /* Each character is its own list element, and the terminating nul is not included in this list. */ %token CST_STRING -%token CST_WSTRING CST_STRING16 CST_STRING32 +%token CST_WSTRING CST_STRING16 CST_STRING32 CST_U8STRING %token EOF %token CHAR INT BOOL DOUBLE FLOAT VOID INT64 INT32 %token INT128 FLOAT128 COMPLEX COMPLEX128 /* C99 */ -%token NORETURN THREADLOCAL/* C11 */ +%token NORETURN THREADLOCAL ALIGNOFC11 /* ALIGNOF is the GCC attribute */ ALIGNAS /* C11 */ %token ENUM STRUCT TYPEDEF UNION %token SIGNED UNSIGNED LONG SHORT %token VOLATILE EXTERN STATIC CONST RESTRICT AUTO REGISTER HIDDEN @@ -328,7 +341,7 @@ let transformOffsetOf (speclist, dtype) member = %left INF_INF SUP_SUP %left PLUS MINUS %left STAR SLASH PERCENT CONST RESTRICT VOLATILE COMPLEX HIDDEN -%right EXCLAM TILDE PLUS_PLUS MINUS_MINUS CAST RPAREN ADDROF SIZEOF ALIGNOF IMAG REAL CLASSIFYTYPE +%right EXCLAM TILDE PLUS_PLUS MINUS_MINUS CAST RPAREN ADDROF SIZEOF ALIGNOF ALIGNOFC11 IMAG REAL CLASSIFYTYPE %left LBRACKET %left DOT ARROW LPAREN LBRACE %right NAMED_TYPE /* We'll use this to handle redefinitions of @@ -345,7 +358,7 @@ let transformOffsetOf (speclist, dtype) member = %type attributes attributes_with_asm asmattr %type statement %type constant -%type string_constant +%type string_constant %type expression %type opt_expression %type init_expression @@ -353,8 +366,8 @@ let transformOffsetOf (speclist, dtype) member = %type paren_comma_expression %type arguments %type bracket_comma_expression -%type string_list -%type wstring_list +/* %type string_list */ +/* %type wstring_list */ %type initializer %type <(Cabs.initwhat * Cabs.init_expression) list> initializer_list @@ -413,11 +426,11 @@ global: | function_def { $1 } /*(* Some C header files ar shared with the C++ compiler and have linkage * specification *)*/ -| EXTERN string_constant declaration { LINKAGE (fst $2, (*handleLoc*) (snd $2), [ $3 ]) } -| EXTERN string_constant LBRACE globals RBRACE - { LINKAGE (fst $2, (*handleLoc*) (snd $2), $4) } +| EXTERN string_constant declaration { let q,t,l = $2 in LINKAGE (queue_to_string q, (*handleLoc*) l, [ $3 ]) } +| EXTERN string_constant LBRACE globals RBRACE + { let q,t,l = $2 in LINKAGE (queue_to_string q, (*handleLoc*) l, $4) } | ASM LPAREN string_constant RPAREN SEMICOLON - { GLOBASM (fst $3, (*handleLoc*) $1) } + { let q,t,l = $3 in GLOBASM (queue_to_string q, (*handleLoc*) $1) } | pragma { $1 } /* (* Old-style function prototype. This should be somewhere else, like in * "declaration". For now we keep it at global scope only because in local @@ -539,6 +552,10 @@ unary_expression: /*(* 6.5.3 *)*/ {EXPR_ALIGNOF (fst $2), $1} | ALIGNOF LPAREN type_name RPAREN {let b, d = $3 in TYPE_ALIGNOF (b, d), $1} +| ALIGNOFC11 unary_expression + {EXPR_ALIGNOF_C11 (fst $2), $1} +| ALIGNOFC11 LPAREN type_name RPAREN + {let b, d = $3 in TYPE_ALIGNOF_C11 (b, d), $1} | PLUS cast_expression {UNARY (PLUS, fst $2), $1} | MINUS cast_expression @@ -700,50 +717,85 @@ constant: | CST_WCHAR {CONST_WCHAR (fst $1, WCHAR_T), snd $1} | CST_CHAR16 {CONST_WCHAR (fst $1, CHAR16_T), snd $1} | CST_CHAR32 {CONST_WCHAR (fst $1, CHAR32_T), snd $1} -| string_constant {CONST_STRING (fst $1), snd $1} +| string_constant { + let queue, typ, location = $1 in + if typ = CHAR then + CONST_STRING (queue_to_string queue), location + else + CONST_WSTRING (queue_to_int64_list queue, typ), location + } +/* | string_constant {CONST_STRING (fst $1), snd $1} | wstring_list {CONST_WSTRING (fst $1, WCHAR_T), snd $1} | string16_list {CONST_WSTRING (fst $1, CHAR16_T), snd $1} -| string32_list {CONST_WSTRING (fst $1, CHAR32_T), snd $1} +| string32_list {CONST_WSTRING (fst $1, CHAR32_T), snd $1} */ ; -string_constant: -/* Now that we know this constant isn't part of a wstring, convert it - back to a string for easy viewing. */ - string_list { - let queue, location = $1 in - let buffer = Buffer.create (Queue.length queue) in - Queue.iter - (List.iter - (fun value -> - let char = int64_to_char value in - Buffer.add_char buffer char)) - queue; - Buffer.contents buffer, location - } -; one_string_constant: /* Don't concat multiple strings. For asm templates. */ CST_STRING {intlist_to_string (fst $1) } ; -string_list: +string_constant: one_string { let queue = Queue.create () in Queue.add (fst $1) queue; - queue, snd $1 + queue, CHAR, snd $1 + } +| CST_WSTRING { + let queue = Queue.create () in + Queue.add (fst $1) queue; + queue, WCHAR_T, snd $1 + } +| CST_STRING16 { + let queue = Queue.create () in + Queue.add (fst $1) queue; + queue, CHAR16_T, snd $1 + } +| CST_STRING32 { + let queue = Queue.create () in + Queue.add (fst $1) queue; + queue, CHAR32_T, snd $1 } -| string_list one_string { - Queue.add (fst $2) (fst $1); - $1 +| string_constant one_string { + let queue, typ, loc = $1 in + Queue.add (fst $2) queue; + queue, typ, loc + } +| string_constant CST_WSTRING { + let queue, typ, loc = $1 in + Queue.add (fst $2) queue; + if typ <> CHAR && typ <> WCHAR_T then ( + parse_error "Incompatible string literals"; + raise Parsing.Parse_error) + else + queue, WCHAR_T, loc + } +| string_constant CST_STRING16 { + let queue, typ, loc = $1 in + Queue.add (fst $2) queue; + if typ <> CHAR && typ <> CHAR16_T then ( + parse_error "Incompatible string literals"; + raise Parsing.Parse_error) + else + queue, CHAR16_T, loc + } +| string_constant CST_STRING32 { + let queue, typ, loc = $1 in + Queue.add (fst $2) queue; + if typ <> CHAR && typ <> CHAR32_T then ( + parse_error "Incompatible string literals"; + raise Parsing.Parse_error) + else + queue, CHAR32_T, loc } ; - +/* wstring_list: CST_WSTRING { $1 } | wstring_list one_string { (fst $1) @ (fst $2), snd $1 } | wstring_list CST_WSTRING { (fst $1) @ (fst $2), snd $1 } | one_string wstring_list { (fst $1) @ (fst $2), snd $1 } /* Only the first string in the list needs an L, so L"a" "b" is the same - * as L"ab" or L"a" L"b". */ + * as L"ab" or L"a" L"b". string16_list: CST_STRING16 { $1 } @@ -753,7 +805,7 @@ string16_list: string32_list: CST_STRING32 { $1 } | string32_list one_string { (fst $1) @ (fst $2), snd $1 } -| string32_list CST_STRING32 { (fst $1) @ (fst $2), snd $1 } +| string32_list CST_STRING32 { (fst $1) @ (fst $2), snd $1 } */ one_string: CST_STRING {$1} @@ -981,6 +1033,9 @@ decl_spec_list: /* ISO 6.7 */ | attribute_nocv decl_spec_list_opt { SpecAttr (fst $1) :: $2, snd $1 } /* specifier pattern variable (must be last in spec list) */ | AT_SPECIFIER LPAREN IDENT RPAREN { [ SpecPattern(fst $3) ], $1 } + /* ISO 6.7.5 */ +| ALIGNAS unary_expression decl_spec_list_opt { SpecAttr ("alignas", [fst $2]) :: $3, $1 } +| ALIGNAS LPAREN type_name RPAREN decl_spec_list_opt { let (b, d) = $3 in ((SpecAttr ("alignas", [TYPE_ALIGNOF_C11 (b,d)]) :: $5), $1) } ; /* (* In most cases if we see a NAMED_TYPE we must shift it. Thus we declare * NAMED_TYPE to have right associativity *) */ @@ -1333,8 +1388,8 @@ attributes_with_asm: /* empty */ { [] } | attribute attributes_with_asm { fst $1 :: $2 } | ASM LPAREN string_constant RPAREN attributes - { ("__asm__", - [CONSTANT(CONST_STRING (fst $3))]) :: $5 } + { let q,t,l = $3 in ("__asm__", + [CONSTANT(CONST_STRING (queue_to_string q))]) :: $5 } ; /* things like __attribute__, but no const/volatile */ @@ -1400,7 +1455,7 @@ primary_attr: | LPAREN attr RPAREN { $2 } | IDENT IDENT { CALL(VARIABLE (fst $1), [VARIABLE (fst $2)]) } | CST_INT { CONSTANT(CONST_INT (fst $1)) } -| string_constant { CONSTANT(CONST_STRING (fst $1)) } +| string_constant { let q,t,l = $1 in CONSTANT(CONST_STRING (queue_to_string q)) } /*(* Const when it appears in * attribute lists, is translated * to aconst *)*/ @@ -1446,6 +1501,8 @@ unary_attr: | ALIGNOF unary_expression {EXPR_ALIGNOF (fst $2) } | ALIGNOF LPAREN type_name RPAREN {let b, d = $3 in TYPE_ALIGNOF (b, d)} +| ALIGNOFC11 unary_expression {EXPR_ALIGNOF_C11 (fst $2) } +| ALIGNOFC11 LPAREN type_name RPAREN {let b, d = $3 in TYPE_ALIGNOF_C11 (b, d)} | PLUS cast_attr {UNARY (PLUS, $2)} | MINUS cast_attr {UNARY (MINUS, $2)} | STAR cast_attr {UNARY (MEMOF, $2)} @@ -1571,8 +1628,8 @@ asmoperandsne: | asmoperandsne COMMA asmoperand { $3 :: $1 } ; asmoperand: - asmopname string_constant LPAREN expression RPAREN { ($1, fst $2, fst $4) } -| asmopname string_constant LPAREN error RPAREN { ($1, fst $2, NOTHING ) } + asmopname string_constant LPAREN expression RPAREN { let q,t,l = $2 in ($1, queue_to_string q, fst $4) } +| asmopname string_constant LPAREN error RPAREN { let q,t,l = $2 in ($1, queue_to_string q, NOTHING ) } ; asminputs: /* empty */ { ([], []) } From ad69b97b44860b2e1926eeb65d7b57c67c0a98f0 Mon Sep 17 00:00:00 2001 From: Baris Coslu Date: Tue, 8 Sep 2020 01:45:57 +0300 Subject: [PATCH 06/16] generic --- src/cil.ml | 108 ++++++++++++++++++++++++++--------- src/cil.mli | 6 +- src/ext/ccl/ccl.ml | 2 +- src/ext/cqualann/cqualann.ml | 4 +- src/ext/llvm/llvmgen.ml | 2 +- src/ext/pta/ptranal.ml | 2 +- src/formatparse.mly | 4 +- src/frontc/cabs.ml | 7 ++- src/frontc/cabs2cil.ml | 73 ++++++++++++++++------- src/frontc/cabsvisit.ml | 1 + src/frontc/clexer.mll | 3 +- src/frontc/cparser.mly | 66 ++++++++++----------- src/frontc/cprint.ml | 6 +- 13 files changed, 188 insertions(+), 96 deletions(-) diff --git a/src/cil.ml b/src/cil.ml index bd20a642f..db4558f95 100755 --- a/src/cil.ml +++ b/src/cil.ml @@ -277,6 +277,7 @@ and typ = | TBuiltin_va_list of attributes (** This is the same as the gcc's type with the same name *) + | TDefault (** Various kinds of integers *) and ikind = @@ -546,9 +547,12 @@ and exp = * It is not printed. Given an lval of type * [TArray(T)] produces an expression of type * [TPtr(T)]. *) + | Generic of exp * ((typ * exp) list) and wstring_type = | Wchar_t | Char16_t | Char32_t +and encoding = No_encoding | Utf8 + (** Literal constants *) and constant = | CInt64 of int64 * ikind * string option @@ -557,7 +561,7 @@ and constant = * {!Cil.integer} or {!Cil.kinteger} to create these. Watch * out for integers that cannot be represented on 64 bits. * OCAML does not give Overflow exceptions. *) - | CStr of string(** String constant (of pointer type) *) + | CStr of string * encoding (** String constant (of pointer type) *) | CWStr of int64 list * wstring_type (** Wide string constant (of type "wchar_t *") *) | CChr of char (** Character constant. This has type int, so use * charConstToInt to read the value in case @@ -1422,7 +1426,7 @@ type attributeClass = let attributeHash: (string, attributeClass) H.t = let table = H.create 13 in List.iter (fun a -> H.add table a (AttrName false)) - [ "section"; "constructor"; "destructor"; "unused"; "used"; "weak"; + [ "section"; "constructor"; "destructor"; "unused"; "used"; "weak"; "no_instrument_function"; "alias"; "no_check_memory_usage"; "exception"; "model"; (* "restrict"; *) "aconst"; "__asm__" (* Gcc uses this to specify the name to be used in @@ -1436,8 +1440,8 @@ let attributeHash: (string, attributeClass) H.t = List.iter (fun a -> H.add table a (AttrFunType false)) [ "format"; "regparm"; "longcall"; - "noinline"; "always_inline"; "gnu_inline"; "leaf"; - "artificial"; "warn_unused_result"; "nonnull"; "c_noreturn"; + "noinline"; "always_inline"; "gnu_inline"; "leaf"; "c_noreturn"; + "artificial"; "warn_unused_result"; "nonnull"; ]; List.iter (fun a -> H.add table a (AttrFunType true)) @@ -1532,6 +1536,7 @@ let rec typeAttrs = function | TEnum (enum, a) -> addAttributes enum.eattr a | TFun (_, _, _, a) -> a | TBuiltin_va_list a -> a + | TDefault -> [] let setTypeAttrs t a = @@ -1546,6 +1551,7 @@ let setTypeAttrs t a = | TEnum (enum, _) -> TEnum (enum, a) | TFun (r, args, v, _) -> TFun(r,args,v,a) | TBuiltin_va_list _ -> TBuiltin_va_list a + | TDefault -> TDefault let typeAddAttributes a0 t = @@ -1568,6 +1574,7 @@ begin | TComp (comp, a) -> TComp (comp, add a) | TNamed (t, a) -> TNamed (t, add a) | TBuiltin_va_list a -> TBuiltin_va_list (add a) + | TDefault -> TDefault end let typeRemoveAttributes (anl: string list) t = @@ -1583,6 +1590,7 @@ let typeRemoveAttributes (anl: string list) t = | TComp (comp, a) -> TComp (comp, drop a) | TNamed (t, a) -> TNamed (t, drop a) | TBuiltin_va_list a -> TBuiltin_va_list (drop a) + | TDefault -> TDefault let unrollType (t: typ) : typ = let rec withAttrs (al: attributes) (t: typ) : typ = @@ -1652,7 +1660,7 @@ let getComplexFkind = function let var vi : lval = (Var vi, NoOffset) (* let assign vi e = Instrs(Set (var vi, e), lu) *) -let mkString s = Const(CStr s) +let mkString s = Const(CStr (s, No_encoding)) let mkWhile ~(guard:exp) ~(body: stmt list) : stmt list = @@ -1790,7 +1798,7 @@ let d_const () c = text (prefix ^ (Int64.to_string i ^ suffix)) ) - | CStr(s) -> text ("\"" ^ escape_string s ^ "\"") + | CStr(s, enc) -> let prefix = match enc with No_encoding -> "" | Utf8 -> "u8" in text (prefix ^ "\"" ^ escape_string s ^ "\"") | CWStr(s, st) -> (* text ("L\"" ^ escape_string s ^ "\"") *) let prefix = match st with Wchar_t -> "L" | Char16_t -> "u" | Char32_t -> "U" in @@ -1872,6 +1880,7 @@ let getParenthLevel (e: exp) = | Lval(Var _, NoOffset) -> 0 (* Plain variables *) | Const _ -> 0 (* Constants *) + | Generic _ -> 0 (*TODO*) let getParenthLevelAttrParam (a: attrparam) = @@ -1945,7 +1954,7 @@ let rec typeOf (e: exp) : typ = (* The type of a string is a pointer to characters ! The only case when * you would want it to be an array is as an argument to sizeof, but we * have SizeOfStr for that *) - | Const(CStr s) -> !stringLiteralType + | Const(CStr (_, _)) -> !stringLiteralType | Const(CWStr (s,st)) -> TPtr((match st with Wchar_t -> !wcharType | Char16_t -> !char16Type | Char32_t -> !char32Type), []) @@ -1968,6 +1977,7 @@ let rec typeOf (e: exp) : typ = TArray (t,_, a) -> TPtr(t, a) | _ -> E.s (E.bug "typeOf: StartOf on a non-array") end + | Generic (e, lst) -> match lst with (t, e1) :: rest -> typeOf e1 | _ -> voidType and typeOfInit (i: init) : typ = match i with @@ -2257,6 +2267,7 @@ let rec alignOf_int t = | TFun _ as t -> raise (SizeOfError ("function", t)) | TVoid _ as t -> raise (SizeOfError ("void", t)) + | TDefault -> raise (SizeOfError ("default", t)) in match filterAttributes "aligned" (typeAttrs t) @ filterAttributes "alignas" (typeAttrs t) with [] -> @@ -2266,25 +2277,46 @@ let rec alignOf_int t = ignore (warn "ignoring recursive align attributes on %a" (!pd_type) t); alignOfType () - | (Attr(_, [a]) as at)::rest -> begin - if rest <> [] then - ignore (warn "ignoring duplicate align attributes on %a" - (!pd_type) t); - match intOfAttrparam a with - | Some 0 -> alignOfType () + | (Attr(_, [a]) as at)::rest -> + let is_power_of_two n = + let log2 = (log10 (float_of_int n)) /. (log10 2.) in + ceil log2 = floor log2 + in + let rec strictest_alignment (current:int) (lst:attribute list) = + match lst with + [] -> current + | (Attr(_, [a]) as at)::rest -> begin + match intOfAttrparam a with + Some 0 -> strictest_alignment current rest + | Some n -> + if not (is_power_of_two n) then begin + ignore(warn "Invalid alignment value specified by attribute %a\n" (!pd_attr) at); + strictest_alignment current rest + end + else strictest_alignment (max current n) rest + | None -> + ignore (warn "alignment attribute \"%a\" not understood on %a" (!pd_attr) at (!pd_type) t); + strictest_alignment current rest + end + | Attr(_, []) :: rest -> + !M.theMachine.M.alignof_aligned + | at ::_ -> + ignore (warn "alignment attribute \"%a\" not understood on %a" + (!pd_attr) at (!pd_type) t); + strictest_alignment current rest + in + let current = match intOfAttrparam a with + Some 0 -> alignOfType () | Some n -> - let is_power_of_two n = - let log2 = (log10 (float_of_int n)) /. (log10 2.) in - ceil log2 = floor log2 - in if not (is_power_of_two n) then alignOfType (ignore(warn "Invalid alignment value specified by attribute %a\n" (!pd_attr) at)) else n | None -> - ignore (warn "alignment attribute \"%a\" not understood on %a" - (!pd_attr) at (!pd_type) t); - alignOfType () - end + ignore (warn "alignment attribute \"%a\" not understood on %a" + (!pd_attr) at (!pd_type) t); + alignOfType () + in + strictest_alignment current rest | Attr(_, [])::rest -> (* aligned with no arg means a power of two at least as large as any alignment on the system.*) @@ -2579,6 +2611,7 @@ and bitsSizeOf t = 0 | TFun _ -> raise (SizeOfError ("function", t)) + | TDefault -> raise (SizeOfError("default", t)) and addTrailing nrbits roundto = @@ -2856,6 +2889,8 @@ let rec isConstant = function | AddrOf (Mem e, off) | StartOf(Mem e, off) -> isConstant e && isConstantOffset off | AddrOfLabel _ -> true + | Generic _ -> false (*TODO*) + and isConstantOffset = function NoOffset -> true | Field(fi, off) -> isConstantOffset off @@ -3535,7 +3570,7 @@ class defaultCilPrinterClass : cilPrinter = object (self) | Real e -> text "__real__(" ++ self#pExp () e ++ chr ')' | SizeOfStr s -> - text "sizeof(" ++ d_const () (CStr s) ++ chr ')' + text "sizeof(" ++ d_const () (CStr (s, No_encoding)) ++ chr ')' | AlignOf (t) -> text "__alignof__(" ++ self#pType None () t ++ chr ')' @@ -3563,6 +3598,14 @@ class defaultCilPrinterClass : cilPrinter = object (self) | StartOf(lv) -> self#pLval () lv + | Generic(e, lst) -> + let rec print_generic_exp l doc = + match l with + | [] -> doc + | (t, e1) :: rest -> print_generic_exp rest (doc ++ text ", " ++ (self#pType None () t) ++ text ":" ++ self#pExp () e1) + in + text "_Generic(" ++ self#pExp () e ++ print_generic_exp lst nil ++ text ")" + (* Print an expression, given the precedence of the context in which it * appears. *) method private pExpPrec (contextprec: int) () (e: exp) = @@ -4499,6 +4542,7 @@ class defaultCilPrinterClass : cilPrinter = object (self) ++ self#pAttrs () a ++ text " " ++ name + | TDefault -> text "default" (**** PRINTING ATTRIBUTES *********) @@ -4842,6 +4886,7 @@ class plainCilPrinterClass = end | TBuiltin_va_list a -> dprintf "TBuiltin_va_list(%a)" self#pAttrs a + | TDefault -> dprintf "TDefault" (* Some plain pretty-printers. Unlike the above these expose all the @@ -4856,8 +4901,9 @@ class plainCilPrinterClass = (Int64.format fmt i) d_ikind ik (match so with Some s -> s | _ -> "None") - | CStr(s) -> - text ("CStr(\"" ^ escape_string s ^ "\")") + | CStr(s, enc) -> + let enc_string = match enc with No_encoding -> "_" | Utf8 -> "UTF8" in + text ("CStr(\"" ^ escape_string s ^ "\"," ^ enc_string ^ ")") | CWStr(s,_) -> dprintf "CWStr(%a)" d_const c @@ -4908,7 +4954,7 @@ class plainCilPrinterClass = | SizeOfE (e) -> text "sizeofE(" ++ self#pExp () e ++ chr ')' | SizeOfStr (s) -> - text "sizeofStr(" ++ d_const () (CStr s) ++ chr ')' + text "sizeofStr(" ++ d_const () (CStr (s, No_encoding)) ++ chr ')' | AlignOf (t) -> text "__alignof__(" ++ self#pType None () t ++ chr ')' | AlignOfE (e) -> @@ -4924,6 +4970,13 @@ class plainCilPrinterClass = | StartOf lv -> dprintf "StartOf(%a)" self#pLval lv | AddrOf (lv) -> dprintf "AddrOf(%a)" self#pLval lv | AddrOfLabel (sref) -> dprintf "AddrOfLabel(%a)" self#pStmt !sref + | Generic(e, lst) -> + let rec print_generic_exp l doc = + match l with + | [] -> doc + | (t, e1) :: rest -> print_generic_exp rest (doc ++ text "," ++ (self#pType None () t) ++ text ":" ++ self#pExp () e1) + in + text "_Generic(" ++ self#pExp () e ++ text "," ++ print_generic_exp lst nil @@ -5444,6 +5497,8 @@ and childrenExp (vis: cilVisitor) (e: exp) : exp = | StartOf lv -> let lv' = vLval lv in if lv' != lv then StartOf lv' else e + | Generic(e, lst) -> e (*TODO*) + and visitCilInit (vis: cilVisitor) (forglob: varinfo) (atoff: offset) (i: init) : init = @@ -6235,6 +6290,7 @@ let rec typeSigWithAttrs ?(ignoreSign=false) doattr t = TSFun(typeSig rt, (Util.list_map_opt (fun (_, atype, _) -> (typeSig atype)) args), isva, doattr a) | TNamed(t, a) -> typeSigAddAttrs (doattr a) (typeSig t.ttype) | TBuiltin_va_list al -> TSBase (TBuiltin_va_list (doattr al)) + | TDefault -> TSBase (TDefault) let typeSig t = typeSigWithAttrs (fun al -> al) t @@ -6262,7 +6318,7 @@ let typeSigAttrs = function let dExp: doc -> exp = - fun d -> Const(CStr(sprint ~width:!lineLength d)) + fun d -> Const(CStr(sprint ~width:!lineLength d, No_encoding)) let dInstr: doc -> location -> instr = fun d l -> Asm([], [sprint ~width:!lineLength d], [], [], [], l) diff --git a/src/cil.mli b/src/cil.mli index ac6a7f170..e8d5f977d 100644 --- a/src/cil.mli +++ b/src/cil.mli @@ -242,6 +242,7 @@ and typ = | TBuiltin_va_list of attributes (** This is the same as the gcc's type with the same name *) + | TDefault (** There are a number of functions for querying the kind of a type. These are @@ -640,11 +641,14 @@ and exp = * not sure which one to use. In C this operation is implicit, the * [StartOf] operator is not printed. We have it in CIL because it makes * the typing rules simpler. *) + | Generic of exp * ((typ * exp) list) (** {b Constants.} *) and wstring_type = | Wchar_t | Char16_t | Char32_t +and encoding = No_encoding | Utf8 + (** Literal constants *) and constant = | CInt64 of int64 * ikind * string option @@ -653,7 +657,7 @@ and constant = * constant as, for example, 0xF instead of 15.) Use {!Cil.integer} or * {!Cil.kinteger} to create these. Watch out for integers that cannot be * represented on 64 bits. OCAML does not give Overflow exceptions. *) - | CStr of string + | CStr of string * encoding (** String constant. The escape characters inside the string have been * already interpreted. This constant has pointer to character type! The * only case when you would like a string literal to have an array type diff --git a/src/ext/ccl/ccl.ml b/src/ext/ccl/ccl.ml index 861e74799..a1b38b3d0 100644 --- a/src/ext/ccl/ccl.ml +++ b/src/ext/ccl/ccl.ml @@ -1055,7 +1055,7 @@ let rec evaluateExp (e : exp) (state : state) : summary = end; SFacts tFacts end - | Const (CStr s) -> + | Const (CStr (s, _)) -> SFacts (FactSet.singleton ("*", ANT 0)) | Const _ -> begin diff --git a/src/ext/cqualann/cqualann.ml b/src/ext/cqualann/cqualann.ml index 23b0cc3ba..36c775a67 100644 --- a/src/ext/cqualann/cqualann.ml +++ b/src/ext/cqualann/cqualann.ml @@ -300,10 +300,10 @@ class stringVisitor method! vexpr e = begin match e with - Const(CStr s) -> + Const(CStr (s, _)) -> (* ignore (E.log "String without cast: %a\n" d_plainexp e); *) ChangeTo(global4String s false) - | CastE(t, Const(CStr s)) -> + | CastE(t, Const(CStr (s, _))) -> let taint = baseTypeContainsSmallocAttribute t in (* ignore (E.log "%stainted String: %a\n" *) (* (if taint then "" else "Un") d_plainexp e); *) diff --git a/src/ext/llvm/llvmgen.ml b/src/ext/llvm/llvmgen.ml index 8c81ee998..920d5305d 100644 --- a/src/ext/llvm/llvmgen.ml +++ b/src/ext/llvm/llvmgen.ml @@ -589,7 +589,7 @@ class llvmGeneratorClass : llvmGenerator = object (self) method mkConstant (c:constant) : llvmValue = match c with | CInt64 (i, ik, _) -> LInt (i, ik) - | CStr s -> LGetelementptr [ LGlobal (self#addString s); lzerop; lzerop ] + | CStr (s, _) -> LGetelementptr [ LGlobal (self#addString s); lzerop; lzerop ] | CWStr (ws,_) -> LGetelementptr [ LGlobal (self#addWString ws); lzerop; lzerop ] | CChr c -> LInt (Int64.of_int (Char.code c), IInt) | CReal (f, fk, _) -> LFloat (f, fk) diff --git a/src/ext/pta/ptranal.ml b/src/ext/pta/ptranal.ml index a61006d62..fe4a99bf7 100644 --- a/src/ext/pta/ptranal.ml +++ b/src/ext/pta/ptranal.ml @@ -231,7 +231,7 @@ and analyze_expr_as_lval (e : exp) : A.lvalue = and analyze_expr (e : exp ) : A.tau = let result = match e with - Const (CStr s) -> + Const (CStr (s, _)) -> if !model_strings then A.address (A.make_lvalue false diff --git a/src/formatparse.mly b/src/formatparse.mly index 34406bb3a..39109a1f4 100644 --- a/src/formatparse.mly +++ b/src/formatparse.mly @@ -560,11 +560,11 @@ constant: | ARG_g { let currentArg = $1 in ((fun args -> match getArg currentArg args with - Fg s -> Const(CStr s) + Fg s -> Const(CStr (s, No_encoding)) | a -> wrongArgType currentArg "string" a), fun e -> match e with - Const(CStr s) -> + Const(CStr (s, _)) -> Some [ Fg s ] | _ -> None) } diff --git a/src/frontc/cabs.ml b/src/frontc/cabs.ml index d43d43dd7..a7278c42b 100644 --- a/src/frontc/cabs.ml +++ b/src/frontc/cabs.ml @@ -80,6 +80,7 @@ type typeSpecifier = (* Merge all specifiers into one type *) | Tenum of string * enum_item list option * attribute list | TtypeofE of expression (* GCC __typeof__ *) | TtypeofT of specifier * decl_type (* GCC __typeof__ *) + | Tdefault and storage = NO_STORAGE | AUTO | STATIC | EXTERN | REGISTER @@ -285,6 +286,7 @@ and expression = | MEMBEROFPTR of expression * string | GNU_BODY of block | EXPR_PATTERN of string (* pattern variable, and name *) + | GENERIC of expression * ((specifier * expression) list) and constant = | CONST_INT of string (* the textual representation *) @@ -292,7 +294,7 @@ and constant = | CONST_COMPLEX of string (* the textual representation *) | CONST_CHAR of int64 list | CONST_WCHAR of int64 list * wchar_type - | CONST_STRING of string + | CONST_STRING of string * encoding | CONST_WSTRING of int64 list * wchar_type (* ww: wstrings are stored as an int64 list at this point because * we might need to feed the wide characters piece-wise into an @@ -300,7 +302,8 @@ and constant = * doesn't happen we will convert it to an (escaped) string before * passing it to Cil. *) -and wchar_type = WCHAR_T | CHAR16_T | CHAR32_T | CHAR +and wchar_type = WCHAR_T | CHAR16_T | CHAR32_T | CHAR | CHAR_UTF8 +and encoding = NO_ENCODING | UTF8 and init_expression = | NO_INIT diff --git a/src/frontc/cabs2cil.ml b/src/frontc/cabs2cil.ml index f9ef1e61f..f1c980995 100644 --- a/src/frontc/cabs2cil.ml +++ b/src/frontc/cabs2cil.ml @@ -1566,6 +1566,7 @@ let cabsTypeAddAttributes a0 t = | TComp (comp, a) -> TComp (comp, addA0To a) | TNamed (t, a) -> TNamed (t, addA0To a) | TBuiltin_va_list a -> TBuiltin_va_list (addA0To a) + | TDefault -> TDefault end @@ -1823,8 +1824,12 @@ let makeGlobalVarinfo (isadef: bool) (vi: varinfo) : varinfo * bool = (* This may throw an exception Not_found *) let oldvi, oldloc = lookupGlobalVar lookupname in - if oldvi.vthreadlocal <> vi.vthreadlocal then - ignore (E.log "_Thread_local appears in a declaration of '%s' but is not present in every declaration.\n" vi.vname); + if oldvi.vthreadlocal <> vi.vthreadlocal then begin + ignore(warn + "_Thread_local appears in a declaration of '%s' but is not present in every declaration. Previous declaration: %a" + vi.vname d_loc oldloc); + oldvi.vthreadlocal <- false; + end; if debug then ignore (E.log " %s already in the env at loc %a\n" vi.vname d_loc oldloc); @@ -2460,6 +2465,7 @@ let rec doSpecList (suggestedAnonName: string) (* This string will be part of | [A.Tcomplex128] -> TFloat(FComplexFloat128, []) (* Now the other type specifiers *) + | [A.Tdefault] -> TDefault | [A.Tnamed n] -> begin if n = "__builtin_va_list" && !Machdep.theMachine.Machdep.__builtin_va_list then begin @@ -2621,7 +2627,7 @@ let rec doSpecList (suggestedAnonName: string) (* This string will be part of match e' with StartOf(lv) -> typeOfLval lv (* If this is a string literal, then we treat it as in sizeof*) - | Const (CStr s) -> begin + | Const (CStr (s, _)) -> begin match typeOf e' with TPtr(bt, _) -> (* This is the type of array elements *) TArray(bt, Some (SizeOfStr s), []) @@ -2765,7 +2771,7 @@ and doAttr (a: A.attribute) : attribute list = | _ -> ACons (n', []) with Not_found -> ACons(n', []) end - | A.CONSTANT (A.CONST_STRING s) -> AStr s + | A.CONSTANT (A.CONST_STRING (s, _)) -> AStr s | A.CONSTANT (A.CONST_INT str) -> begin match parseInt str with Const (CInt64 (v64,_,_)) -> @@ -3371,7 +3377,7 @@ and doExp (asconst: bool) (* This expression is used as a constant *) | A.PAREN e -> E.s (bug "stripParen") | A.NOTHING when what = ADrop -> finishExp empty (integer 0) intType | A.NOTHING -> - let res = Const(CStr "exp_nothing") in + let res = Const(CStr ("exp_nothing", No_encoding)) in finishExp empty res (typeOf res) (* Do the potential lvalues first *) @@ -3537,11 +3543,15 @@ and doExp (asconst: bool) (* This expression is used as a constant *) *) | A.CONST_WSTRING (ws, wst) -> - let cil_wst = match wst with WCHAR_T -> Wchar_t | CHAR16_T -> Char16_t | CHAR32_T -> Char32_t in + let cil_wst = + match wst with + WCHAR_T -> Wchar_t | CHAR16_T -> Char16_t | CHAR32_T -> Char32_t + | _ -> E.s ("Error in CONST_WSTRING: Not a wchar type"); + in let res = Const(CWStr ((* intlist_to_wstring *) ws, cil_wst)) in finishExp empty res (typeOf res) - | A.CONST_STRING s -> + | A.CONST_STRING (s, enc) -> (* Maybe we burried __FUNCTION__ in there *) let s' = try @@ -3558,7 +3568,8 @@ and doExp (asconst: bool) (* This expression is used as a constant *) s with Not_found -> s in - let res = Const(CStr s') in + let enc' = match enc with NO_ENCODING -> No_encoding | UTF8 -> Utf8 in + let res = Const(CStr (s', enc')) in finishExp empty res (typeOf res) | A.CONST_CHAR char_list -> @@ -3578,6 +3589,7 @@ and doExp (asconst: bool) (* This expression is used as a constant *) | WCHAR_T -> !wcharType, !wcharKind | CHAR16_T -> !char16Type, !char16Kind | CHAR32_T -> !char32Type, !char32Kind + | _ -> E.s ("Error in CONST_WCHAR: not a wchar type"); in let value = reduce_multichar wcType char_list in let result = kinteger64 !wcharKind value in @@ -3611,7 +3623,7 @@ and doExp (asconst: bool) (* This expression is used as a constant *) ignore (E.log "float_of_string %s (%s)\n" str (Printexc.to_string e)); E.hadErrors := true; - let res = Const(CStr "booo CONS_FLOAT") in + let res = Const(CStr ("booo CONS_FLOAT", No_encoding)) in finishExp empty res (typeOf res) end end @@ -3643,7 +3655,7 @@ and doExp (asconst: bool) (* This expression is used as a constant *) ignore (E.log "float_of_string_2 %s (%s)\n" baseint (Printexc.to_string e)); E.hadErrors := true; - let res = Const(CStr "booo CONS_FLOAT") in + let res = Const(CStr ("booo CONS_FLOAT", No_encoding)) in finishExp empty res (typeOf res) end end @@ -3654,10 +3666,10 @@ and doExp (asconst: bool) (* This expression is used as a constant *) finishExp empty (SizeOf(typ)) !typeOfSizeOf (* Intercept the sizeof("string") *) - | A.EXPR_SIZEOF (A.CONSTANT (A.CONST_STRING s)) -> begin + | A.EXPR_SIZEOF (A.CONSTANT (A.CONST_STRING (s, enc))) -> begin (* Process the string first *) - match doExp asconst (A.CONSTANT (A.CONST_STRING s)) (AExp None) with - _, Const(CStr s), _ -> + match doExp asconst (A.CONSTANT (A.CONST_STRING (s, enc))) (AExp None) with + _, Const(CStr (s, enc)), _ -> finishExp empty (SizeOfStr s) !typeOfSizeOf | _ -> E.s (bug "cabs2cil: sizeOfStr") end @@ -4882,6 +4894,26 @@ and doExp (asconst: bool) (* This expression is used as a constant *) | A.EXPR_PATTERN _ -> E.s (E.bug "EXPR_PATTERN in cabs2cil input") + | A.GENERIC (expr, lst) -> + let get_exp tupel = match tupel with _, e, _ -> e in + let exp = get_exp (doExp false expr (AExp None)) in + let rec make_cil_list cabs_l cil_l = match cabs_l with + | [] -> cil_l + | (s, e) :: rest -> make_cil_list rest (((doOnlyType s JUSTBASE),get_exp (doExp false e (AExp None))) :: cil_l) + in + let cil_list = make_cil_list lst [] in + let exp_typ = typeOf exp in + let default_typ = ref voidType in + let typ = + let rec get_typ l = match l with + | (TDefault, e) :: rest -> default_typ := typeOf e; get_typ rest + | (t, e) :: rest -> if t = exp_typ then typeOf e else get_typ rest + | [] -> !default_typ + in + get_typ cil_list + in + finishExp empty (Generic(exp, (make_cil_list lst []))) typ + with e when continueOnError -> begin (*ignore (E.log "error in doExp (%s)" (Printexc.to_string e));*) E.hadErrors := true; @@ -5218,11 +5250,11 @@ and doInit * string into characters *) | TArray(bt, leno, _), (A.NEXT_INIT, - (A.SINGLE_INIT(A.CONSTANT (A.CONST_STRING s))| + (A.SINGLE_INIT(A.CONSTANT (A.CONST_STRING (s, enc)))| A.COMPOUND_INIT [(A.NEXT_INIT, A.SINGLE_INIT(A.CONSTANT - (A.CONST_STRING s)))])) :: restil + (A.CONST_STRING (s, enc))))])) :: restil when (match unrollType bt with TInt((IChar|IUChar|ISChar), _) -> true | TInt _ -> @@ -5571,7 +5603,7 @@ and createGlobal (specs : (typ * storage * bool * bool * A.attribute list)) (* Add the variable to the environment before doing the initializer * because it might refer to the variable itself *) if isFunctionType vi.vtype then begin - if vi.vthreadlocal then E.s (error "Invalid storage class '_Thread_local' for function %s" vi.vname); + if vi.vthreadlocal then ignore (error "Invalid storage class '_Thread_local' for function %s" vi.vname); if inite != A.NO_INIT then E.s (error "Function declaration with initializer (%s)" vi.vname); @@ -5787,7 +5819,7 @@ and createLocal ?allow_var_decl:(allow_var_decl=true) ((_, sto, _, _, _) as spec TArray(_,None, _), _, TArray(_, Some _, _) -> vi.vtype <- et (* Initializing a local array *) | TArray(TInt((IChar|IUChar|ISChar), _) as bt, None, a), - SingleInit(Const(CStr s)), _ -> + SingleInit(Const(CStr (s, enc))), _ -> vi.vtype <- TArray(bt, Some (integer (String.length s + 1)), a) @@ -6249,7 +6281,8 @@ and doDecl (isglobal: bool) : A.definition -> chunk = function | Call (None, Lval (Var e, NoOffset), _, _) -> (* See if this is exit, or if it has the noreturn attribute *) if e.vname = "exit" then false - else if hasAttribute "noreturn" e.vattr then false + else if hasAttribute "noreturn" e.vattr + || hasAttribute "c_noreturn" (match !currentFunctionFDEC.svar.vtype with TFun(_,_,_,attr) -> attr | _ -> []) then false else true | Call _ -> true | Asm _ -> true @@ -6347,8 +6380,8 @@ and doDecl (isglobal: bool) : A.definition -> chunk = function ignore (warn "Body of function %s falls-through and cannot find an appropriate return value" !currentFunctionFDEC.svar.vname); None in - if not (hasAttribute "noreturn" - !currentFunctionFDEC.svar.vattr) then + if not (hasAttribute "noreturn" !currentFunctionFDEC.svar.vattr + || hasAttribute "c_noreturn" (match !currentFunctionFDEC.svar.vtype with TFun(_,_,_,attr) -> attr | _ -> []) ) then !currentFunctionFDEC.sbody.bstmts <- !currentFunctionFDEC.sbody.bstmts @ [mkStmt (Return(retval, endloc))] diff --git a/src/frontc/cabsvisit.ml b/src/frontc/cabsvisit.ml index 846195b4c..cdbb79921 100644 --- a/src/frontc/cabsvisit.ml +++ b/src/frontc/cabsvisit.ml @@ -546,6 +546,7 @@ and childrenExpression vis e = let b' = visitCabsBlock vis b in if b' != b then GNU_BODY b' else e | EXPR_PATTERN _ -> e + | GENERIC _ -> e (*TODO*) and visitCabsInitExpression vis (ie: init_expression) : init_expression = doVisit vis vis#vinitexpr childrenInitExpression ie diff --git a/src/frontc/clexer.mll b/src/frontc/clexer.mll index 3f183485c..bc6803c0b 100644 --- a/src/frontc/clexer.mll +++ b/src/frontc/clexer.mll @@ -231,6 +231,7 @@ let init_lexicon _ = THREAD loc else IDENT ("__thread", loc)); + ("_Generic", fun loc -> GENERIC loc); ] (* Mark an identifier as a type name. The old mapping is preserved and will @@ -547,7 +548,7 @@ rule initial = raise (InternalError ("wide string: " ^ Printexc.to_string e))} | "U\"" {try CST_STRING32(str lexbuf, currentLoc ()) with e -> - raise (InternalError ("wide string: " ^ Printexc.to_string e))} + raise (InternalError ("wide string: " ^ Printexc.to_string e))} | floatnum {CST_FLOAT (Lexing.lexeme lexbuf, currentLoc ())} | complexnum {CST_COMPLEX (Lexing.lexeme lexbuf, currentLoc ())} | hexnum {CST_INT (Lexing.lexeme lexbuf, currentLoc ())} diff --git a/src/frontc/cparser.mly b/src/frontc/cparser.mly index 3bf15392f..0ddd2c4d5 100644 --- a/src/frontc/cparser.mly +++ b/src/frontc/cparser.mly @@ -270,7 +270,8 @@ let queue_to_string queue = %token EOF %token CHAR INT BOOL DOUBLE FLOAT VOID INT64 INT32 %token INT128 FLOAT128 COMPLEX COMPLEX128 /* C99 */ -%token NORETURN THREADLOCAL ALIGNOFC11 /* ALIGNOF is the GCC attribute */ ALIGNAS /* C11 */ +%token NORETURN THREADLOCAL ALIGNOFC11 GENERIC /* ALIGNOF is the GCC attribute */ ALIGNAS /* C11 */ +/* %token GENERIC */ %token ENUM STRUCT TYPEDEF UNION %token SIGNED UNSIGNED LONG SHORT %token VOLATILE EXTERN STATIC CONST RESTRICT AUTO REGISTER HIDDEN @@ -489,8 +490,19 @@ primary_expression: /*(* 6.5.1. *)*/ /*(* Next is Scott's transformer *)*/ | AT_EXPR LPAREN IDENT RPAREN /* expression pattern variable */ { EXPR_PATTERN(fst $3), $1 } +| GENERIC LPAREN assignment_expression COMMA generic_assoc_list RPAREN {GENERIC ((fst $3), $5), $1} ; +/* (specifier, expression) list */ +generic_assoc_list: +| generic_association {[$1]} +| generic_assoc_list COMMA generic_association {$3 :: $1} + +/* specifier, expression */ +generic_association: +| type_name COLON assignment_expression {fst $1, fst $3} +| DEFAULT COLON assignment_expression {[SpecType(Tdefault)], fst $3} + postfix_expression: /*(* 6.5.2 *)*/ | primary_expression { $1 } @@ -719,15 +731,11 @@ constant: | CST_CHAR32 {CONST_WCHAR (fst $1, CHAR32_T), snd $1} | string_constant { let queue, typ, location = $1 in - if typ = CHAR then - CONST_STRING (queue_to_string queue), location - else - CONST_WSTRING (queue_to_int64_list queue, typ), location + match typ with + | CHAR -> CONST_STRING (queue_to_string queue, NO_ENCODING), location + | CHAR_UTF8 -> CONST_STRING (queue_to_string queue, UTF8), location + | _ -> CONST_WSTRING (queue_to_int64_list queue, typ), location } -/* | string_constant {CONST_STRING (fst $1), snd $1} -| wstring_list {CONST_WSTRING (fst $1, WCHAR_T), snd $1} -| string16_list {CONST_WSTRING (fst $1, CHAR16_T), snd $1} -| string32_list {CONST_WSTRING (fst $1, CHAR32_T), snd $1} */ ; one_string_constant: @@ -737,8 +745,9 @@ one_string_constant: string_constant: one_string { let queue = Queue.create () in - Queue.add (fst $1) queue; - queue, CHAR, snd $1 + let str, typ, loc = $1 in + Queue.add str queue; + queue, typ, loc } | CST_WSTRING { let queue = Queue.create () in @@ -757,8 +766,10 @@ string_constant: } | string_constant one_string { let queue, typ, loc = $1 in - Queue.add (fst $2) queue; - queue, typ, loc + let str, typ2, _ = $2 in + Queue.add str queue; + let typ3 = if typ = CHAR_UTF8 || typ2 = CHAR_UTF8 then CHAR_UTF8 else CHAR in + queue, typ3, loc } | string_constant CST_WSTRING { let queue, typ, loc = $1 in @@ -788,31 +799,14 @@ string_constant: queue, CHAR32_T, loc } ; -/* -wstring_list: - CST_WSTRING { $1 } -| wstring_list one_string { (fst $1) @ (fst $2), snd $1 } -| wstring_list CST_WSTRING { (fst $1) @ (fst $2), snd $1 } -| one_string wstring_list { (fst $1) @ (fst $2), snd $1 } -/* Only the first string in the list needs an L, so L"a" "b" is the same - * as L"ab" or L"a" L"b". - -string16_list: - CST_STRING16 { $1 } -| string16_list one_string { (fst $1) @ (fst $2), snd $1 } -| string16_list CST_STRING16 { (fst $1) @ (fst $2), snd $1 } - -string32_list: - CST_STRING32 { $1 } -| string32_list one_string { (fst $1) @ (fst $2), snd $1 } -| string32_list CST_STRING32 { (fst $1) @ (fst $2), snd $1 } */ one_string: - CST_STRING {$1} + CST_STRING {fst $1, CHAR, snd $1} +| CST_U8STRING {fst $1, CHAR_UTF8, snd $1} | FUNCTION__ {(Cabshelper.explodeStringToInts - !currentFunctionName), $1} + !currentFunctionName), CHAR, $1} | PRETTY_FUNCTION__ {(Cabshelper.explodeStringToInts - !currentFunctionName), $1} + !currentFunctionName), CHAR, $1} ; init_expression: @@ -1389,7 +1383,7 @@ attributes_with_asm: | attribute attributes_with_asm { fst $1 :: $2 } | ASM LPAREN string_constant RPAREN attributes { let q,t,l = $3 in ("__asm__", - [CONSTANT(CONST_STRING (queue_to_string q))]) :: $5 } + [CONSTANT(CONST_STRING (queue_to_string q, NO_ENCODING))]) :: $5 } ; /* things like __attribute__, but no const/volatile */ @@ -1455,7 +1449,7 @@ primary_attr: | LPAREN attr RPAREN { $2 } | IDENT IDENT { CALL(VARIABLE (fst $1), [VARIABLE (fst $2)]) } | CST_INT { CONSTANT(CONST_INT (fst $1)) } -| string_constant { let q,t,l = $1 in CONSTANT(CONST_STRING (queue_to_string q)) } +| string_constant { let q,t,l = $1 in CONSTANT(CONST_STRING (queue_to_string q, NO_ENCODING)) } /*(* Const when it appears in * attribute lists, is translated * to aconst *)*/ diff --git a/src/frontc/cprint.ml b/src/frontc/cprint.ml index 93e6c440b..3f33cdd2e 100644 --- a/src/frontc/cprint.ml +++ b/src/frontc/cprint.ml @@ -130,11 +130,11 @@ let print_commas nl fct lst = print_list (fun () -> print ","; if nl then new_line() else space()) fct lst; print_maybe "," -let print_string (s:string) = +let print_string (s:string) (enc: encoding) = print ("\"" ^ escape_string s ^ "\"") let print_wstring (s: int64 list ) (wst: Cabs.wchar_type) = - let prefix = match wst with WCHAR_T -> "L" | CHAR16_T -> "u" | CHAR32_T -> "U" in + let prefix = match wst with WCHAR_T -> "L" | CHAR16_T -> "u" | CHAR32_T -> "U" | _ -> Errormsg.s ("Error in print_wstring: not a wchar type") in print (prefix ^ "\"" ^ escape_wstring s ^ "\"") (* @@ -527,7 +527,7 @@ and print_expression_level (lvl: int) (exp : expression) = | CONST_COMPLEX r -> print r | CONST_CHAR c -> print ("'" ^ escape_wstring c ^ "'") | CONST_WCHAR (c, wct) -> print ("L'" ^ escape_wstring c ^ "'") (*TODO*) - | CONST_STRING s -> print_string s + | CONST_STRING (s, enc) -> print_string s enc | CONST_WSTRING (ws, wst) -> print_wstring ws wst) | VARIABLE name -> comprint "variable"; From 898fdf192e91ca7517500d538ebc2a8ebe13aec8 Mon Sep 17 00:00:00 2001 From: Baris Coslu Date: Tue, 10 Nov 2020 15:19:48 +0300 Subject: [PATCH 07/16] Final changes and fix warnings for C11 --- src/check.ml | 12 ++++-- src/cil.ml | 81 ++++++++++++++++++++---------------- src/ext/ccl/ccl.ml | 5 ++- src/ext/llvm/llvmgen.ml | 5 ++- src/ext/llvm/llvmutils.ml | 5 ++- src/ext/pta/ptranal.ml | 3 ++ src/ext/simplify/simplify.ml | 3 +- src/frontc/cabs2cil.ml | 30 +++++++------ src/frontc/clexer.mll | 19 +++++---- src/frontc/cparser.mly | 11 +++-- src/frontc/cprint.ml | 34 +++++++++++++-- src/machdep-ml.c.in | 22 +++++----- 12 files changed, 148 insertions(+), 82 deletions(-) diff --git a/src/check.ml b/src/check.ml index faa54075e..23436f43c 100644 --- a/src/check.ml +++ b/src/check.ml @@ -278,6 +278,7 @@ let rec checkType (t: typ) (ctx: ctxType) = (fun (an, at, aa) -> checkType at CTFArg; checkAttributes aa) (argsToList targs) + | TDefault -> () (* Check that a type is a promoted integral type *) and checkIntegralType (t: typ) = @@ -504,12 +505,12 @@ and checkExp (isconst: bool) (e: exp) : typ = | Imag e -> let te = checkExp isconst e in typeOfRealAndImagComponents te - | AlignOf(t) -> begin + | AlignOf(t) | AlignOf_C11(t) -> begin (* Sizeof cannot be applied to certain types *) checkType t CTSizeof; typeOf e end - | AlignOfE(e') -> + | AlignOfE(e') | AlignOfE_C11(e') -> (* The expression in an AlignOfE can be anything *) let te = checkExp false e' in checkType te CTSizeof; @@ -618,7 +619,12 @@ and checkExp (isconst: bool) (e: exp) : typ = (* | TComp _ -> E.s (bug "Cast of a composite type") *) | TVoid _ -> E.s (bug "Cast of a void type") | _ -> tres - end) + end + | Generic (exp, lst) -> + let typ = checkExp false exp in + List.iter (fun (t, e) -> checkType t CTExp; ignore (checkExp false e)) lst; + typ + ) () (* The argument of withContext *) and checkInit (i: init) : typ = diff --git a/src/cil.ml b/src/cil.ml index db4558f95..2585bf1eb 100755 --- a/src/cil.ml +++ b/src/cil.ml @@ -1977,7 +1977,14 @@ let rec typeOf (e: exp) : typ = TArray (t,_, a) -> TPtr(t, a) | _ -> E.s (E.bug "typeOf: StartOf on a non-array") end - | Generic (e, lst) -> match lst with (t, e1) :: rest -> typeOf e1 | _ -> voidType + | Generic (exp, lst) -> + let typeOfExp = typeOf exp in + let rec findType lst = + match lst with + [] -> voidType + | (t, e) :: rest -> if t = typeOfExp then typeOf e else findType rest + in + findType lst and typeOfInit (i: init) : typ = match i with @@ -2269,6 +2276,33 @@ let rec alignOf_int t = | TVoid _ as t -> raise (SizeOfError ("void", t)) | TDefault -> raise (SizeOfError ("default", t)) in + let is_power_of_two n = + let log2 = (log10 (float_of_int n)) /. (log10 2.) in + ceil log2 = floor log2 + in + let rec strictest_alignment (current:int) (lst:attribute list) = + match lst with + [] -> current + | (Attr(_, [a]) as at)::rest -> begin + match intOfAttrparam a with + Some 0 -> strictest_alignment current rest + | Some n -> + if not (is_power_of_two n) then begin + ignore(warn "Invalid alignment value specified by attribute %a\n" (!pd_attr) at); + strictest_alignment current rest + end + else strictest_alignment (max current n) rest + | None -> + ignore (warn "alignment attribute \"%a\" not understood on %a" (!pd_attr) at (!pd_type) t); + strictest_alignment current rest + end + | Attr(_, []) :: rest -> + strictest_alignment (max current !M.theMachine.M.alignof_aligned) rest; + | at :: rest -> + ignore (warn "alignment attribute \"%a\" not understood on %a" + (!pd_attr) at (!pd_type) t); + strictest_alignment current rest + in match filterAttributes "aligned" (typeAttrs t) @ filterAttributes "alignas" (typeAttrs t) with [] -> (* no __aligned__ attribute, so get the default alignment *) @@ -2278,33 +2312,6 @@ let rec alignOf_int t = (!pd_type) t); alignOfType () | (Attr(_, [a]) as at)::rest -> - let is_power_of_two n = - let log2 = (log10 (float_of_int n)) /. (log10 2.) in - ceil log2 = floor log2 - in - let rec strictest_alignment (current:int) (lst:attribute list) = - match lst with - [] -> current - | (Attr(_, [a]) as at)::rest -> begin - match intOfAttrparam a with - Some 0 -> strictest_alignment current rest - | Some n -> - if not (is_power_of_two n) then begin - ignore(warn "Invalid alignment value specified by attribute %a\n" (!pd_attr) at); - strictest_alignment current rest - end - else strictest_alignment (max current n) rest - | None -> - ignore (warn "alignment attribute \"%a\" not understood on %a" (!pd_attr) at (!pd_type) t); - strictest_alignment current rest - end - | Attr(_, []) :: rest -> - !M.theMachine.M.alignof_aligned - | at ::_ -> - ignore (warn "alignment attribute \"%a\" not understood on %a" - (!pd_attr) at (!pd_type) t); - strictest_alignment current rest - in let current = match intOfAttrparam a with Some 0 -> alignOfType () | Some n -> @@ -2320,10 +2327,7 @@ let rec alignOf_int t = | Attr(_, [])::rest -> (* aligned with no arg means a power of two at least as large as any alignment on the system.*) - if rest <> [] then - ignore(warn "ignoring duplicate align attributes on %a" - (!pd_type) t); - !M.theMachine.M.alignof_aligned + strictest_alignment !M.theMachine.M.alignof_aligned rest | at::_ -> ignore (warn "alignment attribute \"%a\" not understood on %a" (!pd_attr) at (!pd_type) t); @@ -2342,6 +2346,16 @@ and intOfAttrparam (a:attrparam) : int option = AInt(n) -> n | ABinOp(Shiftlt, a1, a2) -> (doit a1) lsl (doit a2) | ABinOp(Div, a1, a2) -> (doit a1) / (doit a2) + | ABinOp(PlusA, a1, a2) -> (doit a1) + (doit a2) + | ABinOp(MinusA, a1, a2) -> (doit a1) - (doit a2) + | ABinOp(Mult, a1, a2) -> (doit a1) * (doit a2) + | ABinOp(Shiftrt, a1, a2) -> (doit a1) lsr (doit a2) + | ABinOp(BAnd, a1, a2) -> (doit a1) land (doit a2) + | ABinOp(BOr, a1, a2) -> (doit a1) lor (doit a2) + | ABinOp(BXor, a1, a2) -> (doit a1) lxor (doit a2) + | ABinOp(LAnd, a1, a2) -> (doit a1) land (doit a2) + | ABinOp(LOr, a1, a2) -> (doit a1) lor (doit a2) + | AUnOp(Neg, a1) -> -(doit a1) | ASizeOf(t) -> let bs = bitsSizeOf t in bs / 8 @@ -2722,12 +2736,9 @@ and constFold (machdep: bool) (e: exp) : exp = | _ -> constFold machdep (AlignOf (typeOf e)) end | AlignOfE_C11 e when machdep -> begin - (* The alignment of an expression is not always the alignment of its - * type. I know that for strings this is not true *) match e with Const (CStr _) when not !msvcMode -> kinteger !kindOfSizeOf !M.theMachine.M.alignof_str - (* For an array, it is the alignment of the array ! *) | _ -> constFold machdep (AlignOf_C11 (typeOf e)) end diff --git a/src/ext/ccl/ccl.ml b/src/ext/ccl/ccl.ml index a1b38b3d0..e637329d7 100644 --- a/src/ext/ccl/ccl.ml +++ b/src/ext/ccl/ccl.ml @@ -1074,12 +1074,15 @@ let rec evaluateExp (e : exp) (state : state) : summary = end; evaluateExp e' state | AlignOf _ - | AlignOfE _ -> SNone + | AlignOfE _ + | AlignOf_C11 _ + | AlignOfE_C11 _ -> SNone | StartOf lv -> evaluateLval lv state | Question _ -> E.s (E.unimp "ternary operator ?:") | AddrOfLabel _ -> E.s (E.unimp "address of label") | Real _ -> E.s (E.unimp "real") | Imag _ -> E.s (E.unimp "imag") + | Generic _ -> E.s (E.unimp "generic") and evaluateLval (lv : lval) (state : state) : summary = match lv with diff --git a/src/ext/llvm/llvmgen.ml b/src/ext/llvm/llvmgen.ml index 920d5305d..aed1d9be3 100644 --- a/src/ext/llvm/llvmgen.ml +++ b/src/ext/llvm/llvmgen.ml @@ -992,8 +992,8 @@ class llvmGeneratorClass : llvmGenerator = object (self) | SizeOf t -> iExp (sizeOf t) | SizeOfE e -> iExp (sizeOf (typeOf e)) | SizeOfStr s -> ([], LInt (Int64.of_int ((String.length s) + 1), !kindOfSizeOf)) - | AlignOf t -> ([], LInt (Int64.of_int (alignOf_int t), !kindOfSizeOf)) - | AlignOfE e -> ([], LInt (Int64.of_int (alignOf_int (typeOf e)), !kindOfSizeOf)) + | AlignOf t | AlignOf_C11 t-> ([], LInt (Int64.of_int (alignOf_int t), !kindOfSizeOf)) + | AlignOfE e | AlignOfE_C11 e -> ([], LInt (Int64.of_int (alignOf_int (typeOf e)), !kindOfSizeOf)) | Lval lv -> iRLval lv | UnOp (op, e, t) -> iUnop op e t | BinOp (op, e1, e2, t) -> iBinop op e1 e2 t @@ -1004,6 +1004,7 @@ class llvmGeneratorClass : llvmGenerator = object (self) | Real e -> raise (Unimplemented "Real") | AddrOfLabel _ -> raise (Unimplemented "AddrOfLabel") | Question _ -> raise (Unimplemented "Question") + | Generic _ -> raise (Unimplemented "Generic") and iUnop op (e:exp) (t:typ) : llvmInstruction list * llvmValue = let (il,v) = iExp e in diff --git a/src/ext/llvm/llvmutils.ml b/src/ext/llvm/llvmutils.ml index 2a4dec107..ada14577b 100644 --- a/src/ext/llvm/llvmutils.ml +++ b/src/ext/llvm/llvmutils.ml @@ -31,7 +31,6 @@ *) open Cil open Pretty -open List exception Unimplemented of string exception Bug @@ -146,6 +145,8 @@ and gType (t:typ) : doc = match t with | TFloat (FComplexFloat, _) -> text "float" (* TODO: Incorrect *) | TFloat (FComplexDouble, _) -> text "double" (* TODO: Incorrect *) | TFloat (FComplexLongDouble, _) -> text "fp128" (* TODO: Incorrect *) +| TFloat (FFloat128, _) -> text "__float128" (* TODO? *) +| TFloat (FComplexFloat128, _) -> text "__complex128" (* TODO? *) | TPtr (t, _) -> (* LLVM uses "i8 *" for 'void *' *) if isVoidType t then text "i8 *" @@ -159,6 +160,8 @@ and gType (t:typ) : doc = match t with | TComp (ci, _) -> (text "%struct.") ++ (text ci.cname) | TEnum (ei, _) -> dprintf "i%d" (bitsSizeOf t) | TBuiltin_va_list _ -> text "i8 *" +| TDefault -> text "default" (* TODO? *) + (* Convert a CIL type 't' to an LLVM type (as a doc string), for use with dprintf's %a *) and dgType () = gType diff --git a/src/ext/pta/ptranal.ml b/src/ext/pta/ptranal.ml index fe4a99bf7..cc67908f0 100644 --- a/src/ext/pta/ptranal.ml +++ b/src/ext/pta/ptranal.ml @@ -257,6 +257,9 @@ and analyze_expr (e : exp ) : A.tau = | SizeOfE _ -> A.bottom () | Imag __ -> failwith "not implemented yet" | Real __ -> failwith "not implemented yet" + | AlignOf_C11 _ -> A.bottom () + | AlignOfE_C11 _ -> A.bottom () + | Generic (_, _) -> failwith "not implemented yet" in H.add expressions e result; result diff --git a/src/ext/simplify/simplify.ml b/src/ext/simplify/simplify.ml index b022ddda7..ecc057691 100644 --- a/src/ext/simplify/simplify.ml +++ b/src/ext/simplify/simplify.ml @@ -121,7 +121,7 @@ let rec makeThreeAddress * return that temp *) (e: exp) : taExp = match e with - SizeOf _ | SizeOfE _ | AlignOf _ | AlignOfE _ | SizeOfStr _ -> + SizeOf _ | SizeOfE _ | AlignOf _ | AlignOfE _ | SizeOfStr _ | AlignOf_C11 _ | AlignOfE_C11 _ -> constFold true e | Const _ -> e | AddrOf (Var _, NoOffset) -> e @@ -156,6 +156,7 @@ let rec makeThreeAddress | StartOf lv -> makeThreeAddress setTemp (AddrOf (addOffsetLval (Index(zero, NoOffset)) lv)) + | Generic (_, _) -> e (* TODO *) (* Make a basic expression *) and makeBasic (setTemp: taExp -> bExp) (e: exp) : bExp = diff --git a/src/frontc/cabs2cil.ml b/src/frontc/cabs2cil.ml index f1c980995..c4de6686e 100644 --- a/src/frontc/cabs2cil.ml +++ b/src/frontc/cabs2cil.ml @@ -534,6 +534,9 @@ let docEnv () = H.iter (fun k d -> acc := (k, d) :: !acc) env; docList ~sep:line (fun (k, d) -> dprintf " %s -> %a" k doone d) () !acc + let rec stripParenLocal e = match e with + | A.PAREN e2 -> stripParenLocal e2 + | _ -> e (* Add a new variable. Do alpha-conversion if necessary *) @@ -659,6 +662,7 @@ let rec stripConstLocalType (t: typ) : typ = let a' = dc a in if a != a' then TVoid a' else t | TBuiltin_va_list a -> let a' = dc a in if a != a' then TBuiltin_va_list a' else t + | TDefault -> t let constFoldTypeVisitor = object (self) @@ -4895,24 +4899,29 @@ and doExp (asconst: bool) (* This expression is used as a constant *) | A.EXPR_PATTERN _ -> E.s (E.bug "EXPR_PATTERN in cabs2cil input") | A.GENERIC (expr, lst) -> - let get_exp tupel = match tupel with _, e, _ -> e in - let exp = get_exp (doExp false expr (AExp None)) in - let rec make_cil_list cabs_l cil_l = match cabs_l with + let get_exp (_, e, _) = e in + let exp = get_exp (doExp false (stripParenLocal expr) (AExp None)) in + let cil_list = + let rec make_cil_list cabs_l cil_l = match cabs_l with | [] -> cil_l - | (s, e) :: rest -> make_cil_list rest (((doOnlyType s JUSTBASE),get_exp (doExp false e (AExp None))) :: cil_l) + | (s, e) :: rest -> make_cil_list rest (((doOnlyType s JUSTBASE),get_exp (doExp false (stripParenLocal e) (AExp None))) :: cil_l) + in + make_cil_list lst [] in - let cil_list = make_cil_list lst [] in let exp_typ = typeOf exp in let default_typ = ref voidType in let typ = - let rec get_typ l = match l with + let rec get_typ lst = match lst with | (TDefault, e) :: rest -> default_typ := typeOf e; get_typ rest | (t, e) :: rest -> if t = exp_typ then typeOf e else get_typ rest - | [] -> !default_typ + | [] -> + if !default_typ = voidType then + E.s(error "Controlling expression of generic selection is not compatible with any association") + else !default_typ in get_typ cil_list in - finishExp empty (Generic(exp, (make_cil_list lst []))) typ + finishExp empty (Generic(exp, (cil_list))) typ with e when continueOnError -> begin (*ignore (E.log "error in doExp (%s)" (Printexc.to_string e));*) @@ -6882,11 +6891,6 @@ and doStatement (s : A.statement) : chunk = consLabel "booo_statement" empty (convLoc (C.get_statementloc s)) false end - -let rec stripParenLocal e = match e with - | A.PAREN e2 -> stripParenLocal e2 - | _ -> e - class stripParenClass : V.cabsVisitor = object (self) inherit V.nopCabsVisitor diff --git a/src/frontc/clexer.mll b/src/frontc/clexer.mll index bc6803c0b..60974b2a3 100644 --- a/src/frontc/clexer.mll +++ b/src/frontc/clexer.mll @@ -350,7 +350,7 @@ let scan_oct_escape str = let utf8_representation value = let generate_bytes n = let first_byte = - let first_byte_prefix = match n with 1 -> 0L | 2 -> 0xC0L | 3 -> 0xE0L | 4 -> 0xF0L in + let first_byte_prefix = match n with 1 -> 0L | 2 -> 0xC0L | 3 -> 0xE0L | 4 -> 0xF0L | _ -> E.s(error "error in utf8_representation"); in Int64.logor first_byte_prefix (Int64.shift_right_logical value (6*(n-1))) in let rec generate_one bytes n = @@ -375,11 +375,13 @@ let lex_simple_escape remainder lexbuf = let prefix = scan_escape lexchar in prefix :: remainder lexbuf -let lex_universal_escape ?is_char:(is_char=false) remainder lexbuf = +let lex_universal_escape ischar remainder lexbuf = let value = scan_hex_escape (Lexing.lexeme lexbuf) in - let prefix = utf8_representation value in - if is_char then (List.hd prefix) :: remainder lexbuf - else List.rev_append prefix (remainder lexbuf) + if ischar then + value :: remainder lexbuf + else + let prefix = utf8_representation value in + List.rev_append prefix (remainder lexbuf) let lex_unescaped remainder lexbuf = let prefix = Int64.of_int (Char.code (Lexing.lexeme_char lexbuf 0)) in @@ -473,7 +475,8 @@ let blank = [' ' '\t' '\012' '\r']+ let escape = '\\' _ let hex_escape = '\\' ['x' 'X'] hexdigit+ let oct_escape = '\\' octdigit octdigit? octdigit? -let universal_escape = '\\' ('u' hexdigit hexdigit hexdigit hexdigit | 'U' hexdigit hexdigit hexdigit hexdigit hexdigit hexdigit hexdigit hexdigit) +let hexquad = hexdigit hexdigit hexdigit hexdigit +let universal_escape = '\\' ('u' hexquad | 'U' hexquad hexquad) let ident = (letter|'_'|'$'|universal_escape)(letter|decdigit|'_'|'$'|universal_escape)* (* Pragmas that are not parsed by CIL. We lex them as PRAGMA_LINE tokens *) @@ -712,7 +715,7 @@ and str = parse | hex_escape {addLexeme lexbuf; lex_hex_escape str lexbuf} | oct_escape {addLexeme lexbuf; lex_oct_escape str lexbuf} | escape {addLexeme lexbuf; lex_simple_escape str lexbuf} -| universal_escape {addLexeme lexbuf; lex_universal_escape str lexbuf} +| universal_escape {addLexeme lexbuf; lex_universal_escape false str lexbuf} | _ {addLexeme lexbuf; lex_unescaped str lexbuf} and chr = parse @@ -720,7 +723,7 @@ and chr = parse | hex_escape {lex_hex_escape chr lexbuf} | oct_escape {lex_oct_escape chr lexbuf} | escape {lex_simple_escape chr lexbuf} -| universal_escape {lex_universal_escape ~is_char:true chr lexbuf} +| universal_escape {lex_universal_escape true chr lexbuf} | _ {lex_unescaped chr lexbuf} and msasm = parse diff --git a/src/frontc/cparser.mly b/src/frontc/cparser.mly index 0ddd2c4d5..8ac5c8aab 100644 --- a/src/frontc/cparser.mly +++ b/src/frontc/cparser.mly @@ -270,8 +270,7 @@ let queue_to_string queue = %token EOF %token CHAR INT BOOL DOUBLE FLOAT VOID INT64 INT32 %token INT128 FLOAT128 COMPLEX COMPLEX128 /* C99 */ -%token NORETURN THREADLOCAL ALIGNOFC11 GENERIC /* ALIGNOF is the GCC attribute */ ALIGNAS /* C11 */ -/* %token GENERIC */ +%token NORETURN THREADLOCAL GENERIC ALIGNOFC11 /* ALIGNOF is the GCC attribute */ ALIGNAS /* C11 */ %token ENUM STRUCT TYPEDEF UNION %token SIGNED UNSIGNED LONG SHORT %token VOLATILE EXTERN STATIC CONST RESTRICT AUTO REGISTER HIDDEN @@ -768,8 +767,12 @@ string_constant: let queue, typ, loc = $1 in let str, typ2, _ = $2 in Queue.add str queue; - let typ3 = if typ = CHAR_UTF8 || typ2 = CHAR_UTF8 then CHAR_UTF8 else CHAR in - queue, typ3, loc + if typ2 = CHAR_UTF8 && typ <> CHAR && typ <> CHAR_UTF8 then ( + parse_error "Incompatible string literals"; + raise Parsing.Parse_error) + else + let typ3 = if typ2 = CHAR_UTF8 then CHAR_UTF8 else typ in + queue, typ3, loc } | string_constant CST_WSTRING { let queue, typ, loc = $1 in diff --git a/src/frontc/cprint.ml b/src/frontc/cprint.ml index 3f33cdd2e..a22466363 100644 --- a/src/frontc/cprint.ml +++ b/src/frontc/cprint.ml @@ -130,7 +130,7 @@ let print_commas nl fct lst = print_list (fun () -> print ","; if nl then new_line() else space()) fct lst; print_maybe "," -let print_string (s:string) (enc: encoding) = +let print_string (s:string) = print ("\"" ^ escape_string s ^ "\"") let print_wstring (s: int64 list ) (wst: Cabs.wchar_type) = @@ -205,6 +205,7 @@ and print_type_spec = function (print_enum_items enum_items) | TtypeofE e -> printl ["__typeof__";"("]; print_expression e; print ") " | TtypeofT (s,d) -> printl ["__typeof__";"("]; print_onlytype (s, d); print ") " + | Tdefault -> print "default " (* print "struct foo", but with specified keyword and a list of @@ -412,6 +413,9 @@ and get_operator exp = | TYPE_SIZEOF _ -> ("", 16) | EXPR_ALIGNOF exp -> ("", 16) | TYPE_ALIGNOF _ -> ("", 16) + | EXPR_ALIGNOF_C11 exp -> ("", 16) + | TYPE_ALIGNOF_C11 _ -> ("", 16) + | GENERIC _ -> ("", 16) | IMAG exp -> ("", 16) | REAL exp -> ("", 16) | CLASSIFYTYPE exp -> ("", 16) @@ -526,8 +530,10 @@ and print_expression_level (lvl: int) (exp : expression) = | CONST_FLOAT r -> print r | CONST_COMPLEX r -> print r | CONST_CHAR c -> print ("'" ^ escape_wstring c ^ "'") - | CONST_WCHAR (c, wct) -> print ("L'" ^ escape_wstring c ^ "'") (*TODO*) - | CONST_STRING (s, enc) -> print_string s enc + | CONST_WCHAR (c, wct) -> + let prefix = match wct with WCHAR_T -> "L'" | CHAR16_T -> "u'" | CHAR32_T -> "U'" | CHAR_UTF8 -> "u8'" | CHAR -> "" in + print (prefix ^ escape_wstring c ^ "'") + | CONST_STRING (s, enc) -> print_string s | CONST_WSTRING (ws, wst) -> print_wstring ws wst) | VARIABLE name -> comprint "variable"; @@ -547,6 +553,28 @@ and print_expression_level (lvl: int) (exp : expression) = printl ["__alignof__";"("]; print_onlytype (bt, dt); print ")" + | EXPR_ALIGNOF_C11 exp -> + printl ["_Alignof";"("]; + print_expression_level 0 exp; + print ")" + | TYPE_ALIGNOF_C11 (bt,dt) -> + printl ["_Alignof";"("]; + print_onlytype (bt, dt); + print ")" + | GENERIC (exp, lst) -> + let print_generic_list l = + match l with + [] -> () + | (s, e) :: tl -> + print ", "; + print_onlytype (s, JUSTBASE); + print ": "; + print_expression_level 0 e; + in + printl ["_Generic";"("]; + print_expression_level 0 exp; + print_generic_list lst; + print ")" | IMAG exp -> printl ["__imag__";"("]; print_expression_level 0 exp; diff --git a/src/machdep-ml.c.in b/src/machdep-ml.c.in index ed74deb82..1e7d344e8 100644 --- a/src/machdep-ml.c.in +++ b/src/machdep-ml.c.in @@ -201,16 +201,7 @@ int main(int argc, char **argv) long double ld; }; alignof_longdouble = (intptr_t)(&((struct s1*)0)->ld); - } - - // The alignment of __float128 - { - struct s1 { - char c; - __float128 f1; - }; - alignof_float128 = (intptr_t)(&((struct s1*)0)->f1); - } + } // The alignment of a float complex { @@ -252,8 +243,17 @@ int main(int argc, char **argv) alignof_fun = __alignof(main); sizeof_fun = 0; + alignof_float128 = alignof_longdouble; #ifdef __GNUC__ sizeof_fun = sizeof(main); + // The alignment of __float128 + { + struct s1 { + char c; + __float128 f1; + }; + alignof_float128 = (intptr_t)(&((struct s1*)0)->f1); + } #endif // The alignment of anything with __attribute__((aligned)) @@ -299,7 +299,7 @@ int main(int argc, char **argv) (int)sizeof(long double _Complex), alignof_longdoublecomplex, (int)sizeof(__complex128), alignof_complex128, (int)sizeof(void), (int)sizeof(bool), alignof_bool, sizeof_fun, alignof_fun, alignof_str, alignof_aligned, - underscore(TYPE_SIZE_T), underscore(TYPE_WCHAR_T), underscore(TYPE_CHAR16_T), + underscore(TYPE_SIZE_T), underscore(TYPE_WCHAR_T), underscore(TYPE_CHAR16_T), underscore(TYPE_CHAR32_T), char_is_unsigned ? "false" : "true", CONST_STRING_LITERALS, little_endian ? "false" : "true", THREAD_IS_KEYWORD, HAVE_BUILTIN_VA_LIST, UNDERSCORE_NAME); From 2f5569c72e22d5f67a79fe1f4a5c06302d069dae Mon Sep 17 00:00:00 2001 From: Baris Coslu Date: Sat, 14 Nov 2020 16:39:47 +0300 Subject: [PATCH 08/16] threadlocal bug fix --- src/frontc/cabs2cil.ml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/frontc/cabs2cil.ml b/src/frontc/cabs2cil.ml index c4de6686e..15ac85752 100644 --- a/src/frontc/cabs2cil.ml +++ b/src/frontc/cabs2cil.ml @@ -587,8 +587,6 @@ let alphaConvertVarAndAddToEnv (addtoenv: bool) (vi: varinfo) : varinfo = (* Store all locals in the slocals (in reversed order). We'll reverse them * and take out the formals at the end of the function *) if not vi.vglob then - if vi.vthreadlocal && vi.vstorage = NoStorage then - E.s (error "Declaration specifiers of %s in block scope include _Thread_local but do not include static or extern" vi.vname); !currentFunctionFDEC.slocals <- newvi :: !currentFunctionFDEC.slocals; (if addtoenv then @@ -596,6 +594,9 @@ let alphaConvertVarAndAddToEnv (addtoenv: bool) (vi: varinfo) : varinfo = addGlobalToEnv vi.vname (EnvVar newvi) else addLocalToEnv vi.vname (EnvVar newvi)); + + (if not vi.vglob && vi.vthreadlocal && vi.vstorage = NoStorage then + E.s (error "Declaration specifiers of %s in block scope include _Thread_local but do not include static or extern" vi.vname); ); (* ignore (E.log " new=%s\n" newvi.vname); *) From 5545056a72977546e2ed20456d12394ddd976457 Mon Sep 17 00:00:00 2001 From: Julian Erhard Date: Mon, 16 Nov 2020 14:39:19 +0100 Subject: [PATCH 09/16] Add -fcommon flag to gcc invocations in tests. Gcc-10 defaults to -fno-common, which gives an error if there are multiple declarations of the same global variable without the extern storage class specifier. --- test/Makefile | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/Makefile b/test/Makefile index 0731537bd..68853b7e4 100644 --- a/test/Makefile +++ b/test/Makefile @@ -277,7 +277,7 @@ testrun/% : $(SMALL1)/%.ml combine%: $(SMALL1)/combine%_1.c cd $(SMALL1); \ - $(CILLY) $(CFLAGS) -std=gnu90 \ + $(CILLY) $(CFLAGS) -std=gnu90 -fcommon\ $(notdir $(wildcard $(SMALL1)/combine$*_[1-9].c)) \ $(EXEOUT)combine$*.exe cd $(SMALL1); ./combine$*.exe @@ -352,11 +352,11 @@ MYSAFECC := $(CILLY) comb: $(TESTDIR)/small2/comb1.c $(TESTDIR)/small2/comb2.c rm -f $(TESTDIR)/small2/comb.exe cd $(TESTDIR)/small2; \ - $(MYSAFECC) comb1.c $(CONLY) $(OBJOUT) comb1.o; \ - $(MYSAFECC) comb2.c $(CONLY) $(OBJOUT) comb2.o; \ - $(MYSAFECC) comb3.c $(CONLY) $(OBJOUT) comb3.o; \ - $(MYSAFECC) comb4.c $(CONLY) $(OBJOUT) comb4.o; \ - $(MYSAFECC) comb1.o comb2.o comb3.o comb4.o $(EXEOUT)comb.exe + $(MYSAFECC) -fcommon comb1.c $(CONLY) $(OBJOUT) comb1.o; \ + $(MYSAFECC) -fcommon comb2.c $(CONLY) $(OBJOUT) comb2.o; \ + $(MYSAFECC) -fcommon comb3.c $(CONLY) $(OBJOUT) comb3.o; \ + $(MYSAFECC) -fcommon comb4.c $(CONLY) $(OBJOUT) comb4.o; \ + $(MYSAFECC) -fcommon comb1.o comb2.o comb3.o comb4.o $(EXEOUT)comb.exe $(TESTDIR)/small2/comb.exe #call cilly on a .c file, a .i file, a .s file, and a .o file. @@ -367,13 +367,13 @@ mixedcomb: $(TESTDIR)/small2/comb1.c $(TESTDIR)/small2/comb2.c gcc -E -o comb2.i comb2.c; \ gcc -S -o comb3.s comb3.c; \ gcc -c -o comb4.o comb4.c; \ - $(MYSAFECC) comb1.c comb2.i comb3.s comb4.o $(EXEOUT)comb.exe + $(MYSAFECC) -fcommon comb1.c comb2.i comb3.s comb4.o $(EXEOUT)comb.exe $(TESTDIR)/small2/comb.exe # sm: another merger test mergestruct: $(TESTDIR)/small2/mergestruct1.c $(TESTDIR)/small2/mergestruct2.c cd $(TESTDIR)/small2; \ - $(CILLY) mergestruct1.c mergestruct2.c -o mergestruct.exe + $(CILLY) -fcommon mergestruct1.c mergestruct2.c -o mergestruct.exe $(TESTDIR)/small2/mergestruct.exe # sc: this tests for a merger bug in global variables initializations From 204344062e4d374097a99110076372753763d65f Mon Sep 17 00:00:00 2001 From: Michael Schwarz Date: Fri, 4 Dec 2020 09:35:34 +0100 Subject: [PATCH 10/16] Remove comment from testrunc99/c99-universal-character-names --- test/testcil.pl | 1 - 1 file changed, 1 deletion(-) diff --git a/test/testcil.pl b/test/testcil.pl index b53075746..142050e21 100644 --- a/test/testcil.pl +++ b/test/testcil.pl @@ -714,7 +714,6 @@ sub addToGroup { addTest("testrunc99/c99-struct"); addTest("testrunc99/c99-complex"); addTest("testrunc99/c99-universal-character-names"); -addBadComment("testrunc99/c99-universal-character-names", "Universal character names are not yet supported"); addTest("testrunc99/c99-tgmath"); addTest("testrunc99/c99-float-pragma"); addTest("combinec99inline"); From 499cffdb0c28b4cd5e8ef3a01873c1f8d2425704 Mon Sep 17 00:00:00 2001 From: Michael Schwarz Date: Tue, 8 Dec 2020 09:02:06 +0100 Subject: [PATCH 11/16] Run autoconf --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 711026cd3..f494f0515 100755 --- a/configure +++ b/configure @@ -2205,7 +2205,7 @@ ac_config_files="$ac_config_files stamp-h" # Assign here the CIL version numbers CIL_VERSION_MAJOR=1 CIL_VERSION_MINOR=7 -CIL_VERSION_REV=3 +CIL_VERSION_REV=8 CIL_VERSION=$CIL_VERSION_MAJOR.$CIL_VERSION_MINOR.$CIL_VERSION_REV # make sure I haven't forgotten to run autoconf From 2340a04c4d20bc18da8c3177c2b831ac9ac6ca29 Mon Sep 17 00:00:00 2001 From: Michael Schwarz Date: Tue, 8 Dec 2020 09:03:47 +0100 Subject: [PATCH 12/16] Typo --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 349315942..dbfa9f704 100644 --- a/configure.ac +++ b/configure.ac @@ -6,7 +6,7 @@ # script; any text which isn't an M4/autoconf directive gets # copied verbatim to that script. -# also, in general, watch out: the M4 quoting charactes are +# also, in general, watch out: the M4 quoting characters are # the square brackets: [ and ]. if you want to pass brackets # to something, you can quote the brackets with more brackets. # I don't know how to pass a single (unbalanced) bracket .. From 0498ecc2b7c1688c18be605a3eed5525a2a28e7a Mon Sep 17 00:00:00 2001 From: Michael Schwarz Date: Tue, 8 Dec 2020 10:45:33 +0100 Subject: [PATCH 13/16] Don't include uchar.h for OS X --- configure | 200 +++++++++++++++++++++++++++++++++++++++++++----------- m4/cil.m4 | 5 +- 2 files changed, 164 insertions(+), 41 deletions(-) diff --git a/configure b/configure index f494f0515..44aace4f6 100755 --- a/configure +++ b/configure @@ -5519,7 +5519,10 @@ $as_echo_n "checking for real definition of size_t... " >&6; } #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5539,7 +5542,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5561,7 +5567,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5581,7 +5590,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5603,7 +5615,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5623,7 +5638,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5645,7 +5663,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5665,7 +5686,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5687,7 +5711,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5707,7 +5734,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5744,7 +5774,10 @@ $as_echo_n "checking for real definition of wchar_t... " >&6; } #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5764,7 +5797,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5786,7 +5822,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5806,7 +5845,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5828,7 +5870,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5848,7 +5893,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5870,7 +5918,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5890,7 +5941,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5912,7 +5966,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5932,7 +5989,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5969,7 +6029,10 @@ $as_echo_n "checking for real definition of char16_t... " >&6; } #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -5989,7 +6052,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -6011,7 +6077,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -6031,7 +6100,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -6053,7 +6125,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -6073,7 +6148,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -6095,7 +6173,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -6115,7 +6196,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -6137,7 +6221,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -6157,7 +6244,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -6194,7 +6284,10 @@ $as_echo_n "checking for real definition of char32_t... " >&6; } #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -6214,7 +6307,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -6236,7 +6332,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -6256,7 +6355,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -6278,7 +6380,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -6298,7 +6403,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -6320,7 +6428,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -6340,7 +6451,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -6362,7 +6476,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ @@ -6382,7 +6499,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ diff --git a/m4/cil.m4 b/m4/cil.m4 index c0496f756..962a86e96 100644 --- a/m4/cil.m4 +++ b/m4/cil.m4 @@ -5,7 +5,10 @@ AC_DEFUN([__CIL_CHECK_INTEGER_TYPE_TYPE], [ AC_COMPILE_IFELSE([AC_LANG_SOURCE([ #include #include -#include +#if __APPLE__ +#else + #include +#endif /* We define a prototype with one type and the function with another type. This will result in compilation error unless the types are really identical. */ From 9d75c0085af78887b8370c1912cbc6d56abaf6db Mon Sep 17 00:00:00 2001 From: Michael Schwarz Date: Tue, 8 Dec 2020 10:57:46 +0100 Subject: [PATCH 14/16] OS X: Manually define char16_t and char32_t --- configure | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ m4/cil.m4 | 2 ++ 2 files changed, 82 insertions(+) diff --git a/configure b/configure index 44aace4f6..024b77e32 100755 --- a/configure +++ b/configure @@ -5520,6 +5520,8 @@ $as_echo_n "checking for real definition of size_t... " >&6; } #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -5543,6 +5545,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -5568,6 +5572,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -5591,6 +5597,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -5616,6 +5624,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -5639,6 +5649,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -5664,6 +5676,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -5687,6 +5701,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -5712,6 +5728,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -5735,6 +5753,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -5775,6 +5795,8 @@ $as_echo_n "checking for real definition of wchar_t... " >&6; } #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -5798,6 +5820,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -5823,6 +5847,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -5846,6 +5872,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -5871,6 +5899,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -5894,6 +5924,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -5919,6 +5951,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -5942,6 +5976,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -5967,6 +6003,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -5990,6 +6028,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -6030,6 +6070,8 @@ $as_echo_n "checking for real definition of char16_t... " >&6; } #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -6053,6 +6095,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -6078,6 +6122,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -6101,6 +6147,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -6126,6 +6174,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -6149,6 +6199,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -6174,6 +6226,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -6197,6 +6251,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -6222,6 +6278,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -6245,6 +6303,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -6285,6 +6345,8 @@ $as_echo_n "checking for real definition of char32_t... " >&6; } #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -6308,6 +6370,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -6333,6 +6397,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -6356,6 +6422,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -6381,6 +6449,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -6404,6 +6474,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -6429,6 +6501,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -6452,6 +6526,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -6477,6 +6553,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif @@ -6500,6 +6578,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif diff --git a/m4/cil.m4 b/m4/cil.m4 index 962a86e96..9d3c64752 100644 --- a/m4/cil.m4 +++ b/m4/cil.m4 @@ -6,6 +6,8 @@ AC_DEFUN([__CIL_CHECK_INTEGER_TYPE_TYPE], [ #include #include #if __APPLE__ + typedef uint_least16_t char_16_t; + typedef uint_least32_t char_32_t; #else #include #endif From f2d55a8bf65bf752f71210ba79984e249224ac23 Mon Sep 17 00:00:00 2001 From: Michael Schwarz Date: Tue, 8 Dec 2020 11:05:05 +0100 Subject: [PATCH 15/16] Include stdint.h --- configure | 200 ++++++++++++++++++++++++++++++++---------------------- m4/cil.m4 | 5 +- 2 files changed, 123 insertions(+), 82 deletions(-) diff --git a/configure b/configure index 024b77e32..d9aec7839 100755 --- a/configure +++ b/configure @@ -5519,9 +5519,10 @@ $as_echo_n "checking for real definition of size_t... " >&6; } #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -5544,9 +5545,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -5571,9 +5573,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -5596,9 +5599,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -5623,9 +5627,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -5648,9 +5653,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -5675,9 +5681,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -5700,9 +5707,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -5727,9 +5735,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -5752,9 +5761,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -5794,9 +5804,10 @@ $as_echo_n "checking for real definition of wchar_t... " >&6; } #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -5819,9 +5830,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -5846,9 +5858,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -5871,9 +5884,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -5898,9 +5912,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -5923,9 +5938,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -5950,9 +5966,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -5975,9 +5992,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -6002,9 +6020,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -6027,9 +6046,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -6069,9 +6089,10 @@ $as_echo_n "checking for real definition of char16_t... " >&6; } #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -6094,9 +6115,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -6121,9 +6143,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -6146,9 +6169,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -6173,9 +6197,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -6198,9 +6223,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -6225,9 +6251,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -6250,9 +6277,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -6277,9 +6305,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -6302,9 +6331,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -6344,9 +6374,10 @@ $as_echo_n "checking for real definition of char32_t... " >&6; } #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -6369,9 +6400,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -6396,9 +6428,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -6421,9 +6454,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -6448,9 +6482,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -6473,9 +6508,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -6500,9 +6536,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -6525,9 +6562,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -6552,9 +6590,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif @@ -6577,9 +6616,10 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif diff --git a/m4/cil.m4 b/m4/cil.m4 index 9d3c64752..c23dcca6e 100644 --- a/m4/cil.m4 +++ b/m4/cil.m4 @@ -5,9 +5,10 @@ AC_DEFUN([__CIL_CHECK_INTEGER_TYPE_TYPE], [ AC_COMPILE_IFELSE([AC_LANG_SOURCE([ #include #include +#include #if __APPLE__ - typedef uint_least16_t char_16_t; - typedef uint_least32_t char_32_t; + typedef uint_least16_t char16_t; + typedef uint_least32_t char32_t; #else #include #endif From f116315f2aa621c23d4b57aaaa05076f2f89eb42 Mon Sep 17 00:00:00 2001 From: Michael Schwarz Date: Tue, 8 Dec 2020 11:20:53 +0100 Subject: [PATCH 16/16] Ad comment about missing uchar header on Mac --- configure | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ m4/cil.m4 | 3 ++ 2 files changed, 123 insertions(+) diff --git a/configure b/configure index d9aec7839..7a301ad71 100755 --- a/configure +++ b/configure @@ -5521,6 +5521,9 @@ $as_echo_n "checking for real definition of size_t... " >&6; } #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -5547,6 +5550,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -5575,6 +5581,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -5601,6 +5610,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -5629,6 +5641,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -5655,6 +5670,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -5683,6 +5701,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -5709,6 +5730,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -5737,6 +5761,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -5763,6 +5790,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -5806,6 +5836,9 @@ $as_echo_n "checking for real definition of wchar_t... " >&6; } #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -5832,6 +5865,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -5860,6 +5896,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -5886,6 +5925,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -5914,6 +5956,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -5940,6 +5985,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -5968,6 +6016,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -5994,6 +6045,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -6022,6 +6076,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -6048,6 +6105,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -6091,6 +6151,9 @@ $as_echo_n "checking for real definition of char16_t... " >&6; } #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -6117,6 +6180,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -6145,6 +6211,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -6171,6 +6240,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -6199,6 +6271,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -6225,6 +6300,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -6253,6 +6331,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -6279,6 +6360,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -6307,6 +6391,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -6333,6 +6420,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -6376,6 +6466,9 @@ $as_echo_n "checking for real definition of char32_t... " >&6; } #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -6402,6 +6495,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -6430,6 +6526,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -6456,6 +6555,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -6484,6 +6586,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -6510,6 +6615,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -6538,6 +6646,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -6564,6 +6675,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -6592,6 +6706,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else @@ -6618,6 +6735,9 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else diff --git a/m4/cil.m4 b/m4/cil.m4 index c23dcca6e..584e32606 100644 --- a/m4/cil.m4 +++ b/m4/cil.m4 @@ -7,6 +7,9 @@ AC_DEFUN([__CIL_CHECK_INTEGER_TYPE_TYPE], [ #include #include #if __APPLE__ + // C11 7.28 defines these to be the same as uint_least16_t and uint_least32_t. + // The standard mandates a uchar.h file to contain these typedefs, but Mac does + // not have that header file typedef uint_least16_t char16_t; typedef uint_least32_t char32_t; #else