Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add C11 generic support #48

Merged
merged 51 commits into from
Dec 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
203f283
Add C11 generic to Cabs and CIL
coslu Sep 7, 2020
d9a7510
Fix C11 generic warnings
coslu Nov 10, 2020
0067d37
Remove C11 generic from CIL
sim642 Sep 10, 2021
a7cf7e4
Rewrite C11 generic Cabs2cil to resolve generic switch
sim642 Sep 10, 2021
ddd59c1
Implement C11 generic Cabsvisit
sim642 Sep 10, 2021
76e9c83
Remove now unnecessary stripParenLocal from C11 generic Cabs2cil
sim642 Sep 10, 2021
005a453
Move Cabs2cil.stripParenLocal back to its old location
sim642 Sep 10, 2021
e58de49
Add comments about C11 generic
sim642 Sep 10, 2021
50c02c9
Add failing generic test
michael-schwarz Sep 11, 2021
041c7cf
fix error numbers
michael-schwarz Sep 11, 2021
962dc8a
Add type qualifier attribute compatibility check and strip to combine…
sim642 Sep 13, 2021
5f1b78e
Add type qualifier attribute strip to C11 generic combineTypes
sim642 Sep 13, 2021
c2f6339
Add type qualifier attribute strip to function argument combineTypes
sim642 Sep 13, 2021
7cdf8ad
Fix make test printing annoying raw output
sim642 Sep 13, 2021
0b162ca
Fix raw test output in CI
sim642 Sep 13, 2021
9a17ba2
Fix raw test output failing successful tests in CI
sim642 Sep 13, 2021
9473315
Fix make test failure exit code
sim642 Sep 13, 2021
19238f0
Remove useless raw log step in CI
sim642 Sep 13, 2021
06a878c
Remove invalid test with conflicting type qualifiers
sim642 Sep 13, 2021
b4bd664
Document some type functions in Cabs2cil
sim642 Sep 13, 2021
2add3ca
Update comments about C11 generic in Cabs2cil.doExp
sim642 Sep 13, 2021
a6ef80d
Remove outdated comments in small1/c11-generic test
sim642 Sep 13, 2021
897aba2
Move qualifier attributes functions from Cabs2cil to Cil
sim642 Sep 13, 2021
5e9a2f6
Port type qualifier fixes from Cabs2cil.combineTypes to Mergecil.comb…
sim642 Sep 13, 2021
e67879d
Expand Mergecil.combineTypes different type qualifiers message
sim642 Sep 13, 2021
46c6a0a
Fix combineTypes dropping type qualifiers
sim642 Sep 13, 2021
dd8f2f2
Add C11 generic string literal test
sim642 Sep 13, 2021
919c0f8
Add C11 generic test where pointer type fails
sim642 Sep 14, 2021
66b5e81
Fix parsing of pointer types in C11 generic associations
sim642 Sep 14, 2021
f703a1c
Remove const_string_literals from Machdep
sim642 Sep 14, 2021
afafead
Remove ref from Cil.stringLiteralType
sim642 Sep 14, 2021
e84b98b
Expose Cil.stringLiteralType in signature
sim642 Sep 14, 2021
8fc4cc4
Disable broken macOS CI
sim642 Sep 14, 2021
0177bfd
Add C11 generic test where expression without parenthesis breaks
sim642 Sep 15, 2021
8d5204a
Fix C11 generic Cabsvisit dropping simple GENERIC
sim642 Sep 15, 2021
ba391a8
Add C11 generic GCC test 1
sim642 Sep 15, 2021
b13180b
Add C11 generic GCC test 2
sim642 Sep 15, 2021
2be7157
Add C11 generic GCC test 3
sim642 Sep 15, 2021
79a4579
Add main functions to C11 generic GCC tests to prevent failure from GCC
sim642 Sep 15, 2021
1983c12
Disable gcc-c11-generic-2-6 test
sim642 Sep 15, 2021
39d8442
Add C11 generic Clang tests
sim642 Sep 15, 2021
ce4f4f7
Fix pointer qualifier handling in ternary operator typing
sim642 Sep 15, 2021
46e4f05
Fix Cil.isNullPtrConstant to only allow void* casts
sim642 Sep 15, 2021
7a7e1e4
Refactor integer 0 handling in ternary operator typing
sim642 Sep 15, 2021
3dfa002
Add missing void case to ternary operator typing
sim642 Sep 15, 2021
6674fd1
Add separate pconst attribute for tracking whether to print const
sim642 Nov 15, 2021
544dbfc
Revert "Disable broken macOS CI"
sim642 Nov 29, 2021
7606d26
Fix Cprint print_generic_list only printing first association
sim642 Nov 29, 2021
e47e4ad
Simplify Cabs2cil.stripConstLocalType
sim642 Nov 29, 2021
f70e708
Merge branch 'develop' into c11-generic
sim642 Dec 10, 2021
a0a1a94
Add C11 _Generic to CHANGES
sim642 Dec 10, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Add ends to locations, allowing for ranges.
* Add additional expression locations to statements, etc.
* Drop all support for MSVC
* Add C11 `_Generic` support.

## Older versions

Expand Down
3 changes: 1 addition & 2 deletions Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,6 @@ $(OBJDIR)/machdep.ml : src/machdep-ml.c configure.ac Makefile.in
@echo " alignof_fun: int; (* Alignment of function *)" >> $@
@echo " alignof_aligned: int; (* Alignment of anything with the \"aligned\" attribute *)" >> $@
@echo " char_is_unsigned: bool; (* Whether \"char\" is unsigned *)">> $@
@echo " const_string_literals: bool; (* Whether string literals have const chars *)">> $@
@echo " little_endian: bool; (* whether the machine is little endian *)">>$@
@echo " __thread_is_keyword: bool; (* whether __thread is a keyword *)">>$@
@echo " __builtin_va_list: bool; (* whether __builtin_va_list is builtin (gccism) *)">>$@
Expand Down Expand Up @@ -286,7 +285,7 @@ clean: $(CILLYDIR)/Makefile

.PHONY: test
test:
cd test; CC=@CC@ ./testcil -r --regrtest || { cat cil.log; exit 1; }
cd test; CC=@CC@ ./testcil -r --regrtest || { echo "Check test/cil.log for raw output"; exit 1; }

########################################################################

Expand Down
2 changes: 1 addition & 1 deletion doc/cil.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1851,7 +1851,7 @@ \subsection{Specifying a machine model}
short=2,2 int=4,4 long=8,8 long_long=8,8 pointer=8,8 enum=4,4
float=4,4 double=8,8 long_double=16,16 void=1 bool=1,1 fun=1,1
alignof_string=1 max_alignment=16 size_t=unsigned_long
wchar_t=int char_signed=true const_string_literals=true
wchar_t=int char_signed=true
big_endian=false __thread_is_keyword=true
__builtin_va_list=true underscore_name=true
\end{verbatim}
Expand Down
1 change: 1 addition & 0 deletions src/check.ml
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ let typeSigIgnoreConst (t : typ) : typsig =
let attrFilter (attr : attribute) : bool =
match attr with
| Attr ("const", []) -> false
| Attr ("pconst", []) -> false
| _ -> true
in
typeSigWithAttrs (List.filter attrFilter) t
Expand Down
60 changes: 40 additions & 20 deletions src/cil.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1276,8 +1276,8 @@ let charType = TInt(IChar, [])
let boolType = TInt(IBool, [])

let charPtrType = TPtr(charType,[])
let charConstPtrType = TPtr(TInt(IChar, [Attr("const", [])]),[])
let stringLiteralType = ref charPtrType
let charConstPtrType = TPtr(TInt(IChar, [Attr("const", []); Attr("pconst", [])]),[])
let stringLiteralType = charPtrType
michael-schwarz marked this conversation as resolved.
Show resolved Hide resolved

let voidPtrType = TPtr(voidType, [])
let intPtrType = TPtr(intType, [])
Expand Down Expand Up @@ -1523,6 +1523,18 @@ let rec typeAttrs = function
| TFun (_, _, _, a) -> a
| TBuiltin_va_list a -> a

(** [typeAttrs], which doesn't add inner attributes. *)
let typeAttrsOuter = function
| TVoid a -> a
| TInt (_, a) -> a
| TFloat (_, a) -> a
| TNamed (_, a) -> a
| TPtr (_, a) -> a
| TArray (_, _, a) -> a
| TComp (_, a) -> a
| TEnum (_, a) -> a
| TFun (_, _, _, a) -> a
| TBuiltin_va_list a -> a

let setTypeAttrs t a =
match t with
Expand Down Expand Up @@ -1574,6 +1586,19 @@ let typeRemoveAttributes (anl: string list) t =
| TNamed (t, a) -> TNamed (t, drop a)
| TBuiltin_va_list a -> TBuiltin_va_list (drop a)

(** Partition attributes into type qualifiers and non type qualifiers. *)
let partitionQualifierAttributes al =
List.partition (function
| Attr (("const" | "volatile" | "restrict"), []) -> true
| _ -> false
) al

(** Remove top-level type qualifiers from type. *)
let removeOuterQualifierAttributes t =
let a = typeAttrsOuter t in
let (_, a') = partitionQualifierAttributes a in
setTypeAttrs t a'

let unrollType (t: typ) : typ =
let rec withAttrs (al: attributes) (t: typ) : typ =
match t with
Expand Down Expand Up @@ -1910,7 +1935,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 s) -> stringLiteralType

| Const(CWStr s) -> TPtr(!wcharType,[])

Expand Down Expand Up @@ -2149,11 +2174,7 @@ let rec getInteger (e:exp) : cilint option =
let mkInt ik n = Some (fst (truncateCilint ik n)) in
match unrollType t, getInteger e with
| TInt (ik, _), Some n -> mkInt ik n
| TPtr _, Some n -> begin
match !upointType with
TInt (ik, _) -> mkInt ik n
| _ -> raise (Failure "pointer size unknown")
end
(* "integer constant expressions" may not cast to ptr *)
michael-schwarz marked this conversation as resolved.
Show resolved Hide resolved
| TEnum (ei, _), Some n -> mkInt ei.ekind n
| TFloat _, v -> v
| _, _ -> None
Expand Down Expand Up @@ -2671,9 +2692,12 @@ let isArrayType t =

(** 6.3.2.3 subsection 3
* An integer constant expr with value 0, or such an expr cast to void *, is called a null pointer constant. *)
let isNullPtrConstant = function
| CastE(TPtr(TVoid _,_), e) -> isZero @@ constFold true e
| e -> isZero @@ constFold true e
let isNullPtrConstant e =
let rec isNullPtrConstant = function
| CastE (TPtr (TVoid [], []), e) -> isNullPtrConstant e (* no qualifiers allowed on void or ptr *)
| e -> isZero e
in
isNullPtrConstant (constFold true e)

let rec isConstant = function
| Const _ -> true
Expand Down Expand Up @@ -2798,7 +2822,7 @@ let initGccBuiltins () : unit =
let ulongLongType = TInt(IULongLong, []) in
let floatType = TFloat(FFloat, []) in
let longDoubleType = TFloat (FLongDouble, []) in
let voidConstPtrType = TPtr(TVoid [Attr ("const", [])], []) in
let voidConstPtrType = TPtr(TVoid [Attr ("const", []); Attr ("pconst", [])], []) in
let sizeType = !typeOfSizeOf in
let v4sfType = TFloat (FFloat,[Attr("__vector_size__", [AInt 16])]) in

Expand Down Expand Up @@ -4176,7 +4200,7 @@ class defaultCilPrinterClass : cilPrinter = object (self)

| TArray (elemt, lo, a) ->
(* ignore the const attribute for arrays *)
let a' = dropAttributes [ "const" ] a in
let a' = dropAttributes [ "pconst" ] a in
michael-schwarz marked this conversation as resolved.
Show resolved Hide resolved
let name' =
if a' == [] then name else
if nameOpt == None then printAttributes a' else
Expand Down Expand Up @@ -4241,7 +4265,8 @@ class defaultCilPrinterClass : cilPrinter = object (self)
method pAttr (Attr(an, args): attribute) : doc * bool =
(* Recognize and take care of some known cases *)
match an, args with
"const", [] -> text "const", false
"const", [] -> nil, false (* don't print const directly, because of split local declarations *)
| "pconst", [] -> text "const", false (* pconst means print const *)
(* Put the aconst inside the attribute list *)
| "complex", [] when !c99Mode -> text "_Complex", false
| "complex", [] -> text "__complex__", false
Expand Down Expand Up @@ -4805,7 +4830,7 @@ let makeVarinfo global name ?init typ =
{ vname = name;
vid = newVID ();
vglob = global;
vtype = if global then typ else typeRemoveAttributes ["const"] typ;
vtype = if global then typ else typeRemoveAttributes ["pconst"] typ;
michael-schwarz marked this conversation as resolved.
Show resolved Hide resolved
vdecl = lu;
vinit = {init=init};
vinline = false;
Expand Down Expand Up @@ -6712,11 +6737,6 @@ let initCIL () =
Some machine -> M.theMachine := machine
| None -> M.theMachine := M.gcc
end;
(* Pick type for string literals *)
stringLiteralType := if !M.theMachine.M.const_string_literals then
charConstPtrType
else
charPtrType;
Comment on lines -6715 to -6719
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is removing this necessary?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, looks like this is an MSVC thing, which we will no longer support anyway.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it was actually supposed to be a GCC thing, but it didn't even match the typing behavior of GCC: #48 (comment).

(* Find the right ikind given the size *)
let findIkindSz (unsigned: bool) (sz: int) : ikind =
try
Expand Down
13 changes: 13 additions & 0 deletions src/cil.mli
Original file line number Diff line number Diff line change
Expand Up @@ -1332,6 +1332,9 @@ val charType: typ
(** char * *)
val charPtrType: typ

(** Type of string literals *)
val stringLiteralType: typ

(** wchar_t (depends on architecture) and is set when you call
* {!Cil.initCIL}. *)
val wcharKind: ikind ref
Expand Down Expand Up @@ -1799,6 +1802,9 @@ val hasAttribute: string -> attributes -> bool
of the type structure, in case of composite, enumeration and named types *)
val typeAttrs: typ -> attribute list

(** [typeAttrs], which doesn't add inner attributes. *)
val typeAttrsOuter: typ -> attribute list

val setTypeAttrs: typ -> attributes -> typ (* Resets the attributes *)


Expand All @@ -1811,6 +1817,13 @@ val typeAddAttributes: attribute list -> typ -> typ
val typeRemoveAttributes: string list -> typ -> typ


(** Partition attributes into type qualifiers and non type qualifiers. *)
val partitionQualifierAttributes: attribute list -> attribute list * attribute list

(** Remove top-level type qualifiers from type. *)
val removeOuterQualifierAttributes: typ -> typ


(** Convert an expression into an attrparam, if possible. Otherwise raise
NotAnAttrParam with the offending subexpression *)
val expToAttrParam: exp -> attrparam
Expand Down
2 changes: 2 additions & 0 deletions src/frontc/cabs.ml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,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 (** "default" in generic associations *)

and storage =
NO_STORAGE | AUTO | STATIC | EXTERN | REGISTER
Expand Down Expand Up @@ -280,6 +281,7 @@ and expression =
| MEMBEROFPTR of expression * string
| GNU_BODY of block
| EXPR_PATTERN of string (* pattern variable, and name *)
| GENERIC of expression * (((specifier * decl_type) * expression) list)

and constant =
| CONST_INT of string (* the textual representation *)
Expand Down
79 changes: 64 additions & 15 deletions src/frontc/cabs2cil.ml
Original file line number Diff line number Diff line change
Expand Up @@ -603,11 +603,7 @@ let alphaConvertVarAndAddToEnv (addtoenv: bool) (vi: varinfo) : varinfo =
* a struct we must recursively strip the "const" from fields and array
* elements. *)
let rec stripConstLocalType (t: typ) : typ =
let dc a =
if hasAttribute "const" a then
dropAttribute "const" a
else a
in
let dc = dropAttribute "pconst" in
match t with
| TPtr (bt, a) ->
(* We want to be able to detect by pointer equality if the type has
Expand Down Expand Up @@ -1570,7 +1566,16 @@ type combineWhat =
* that are known to be equal *)
let isomorphicStructs : (string * string, bool) H.t = H.create 15

(** Construct the composite type of [oldt] and [t] if they are compatible.
Raise [Failure] if they are incompatible. *)
let rec combineTypes (what: combineWhat) (oldt: typ) (t: typ) : typ =
let (oldq, olda) = partitionQualifierAttributes (typeAttrsOuter oldt) in
let (q, a) = partitionQualifierAttributes (typeAttrsOuter t) in
if oldq <> q then
raise (Failure "different type qualifiers")
else if q <> [] then
cabsTypeAddAttributes q (combineTypes what (setTypeAttrs oldt olda) (setTypeAttrs t a))
else
match oldt, t with
| TVoid olda, TVoid a -> TVoid (cabsAddAttributes olda a)
| TInt (oldik, olda), TInt (ik, a) ->
Expand Down Expand Up @@ -1743,7 +1748,7 @@ let rec combineTypes (what: combineWhat) (oldt: typ) (t: typ) : typ =
combineTypes
(if what = CombineFundef then
CombineFunarg else CombineOther)
ot' at
(removeOuterQualifierAttributes ot') (removeOuterQualifierAttributes at)
in
let a = addAttributes oa aa in
(n, t, a))
Expand Down Expand Up @@ -1883,19 +1888,33 @@ let conditionalConversion (t2: typ) (t3: typ) (e2: exp option) (e3:exp) : typ =
arithmeticConversion t2 t3
| TComp (comp2,_), TComp (comp3,_), _
when comp2.ckey = comp3.ckey -> t2
| TPtr(_, _), TPtr(TVoid _, _), _ ->
if isNullPtrConstant e3 then t2 else t3
| TPtr(TVoid _, _), TPtr(_, _), Some e2' ->
if isNullPtrConstant e2' then t3 else t2
| TVoid [], TVoid [], _ -> TVoid [] (* TODO: what about qualifiers? standard says nothing *)
| TPtr(_, _), _, _ when isNullPtrConstant e3 -> t2
| _, TPtr(_, _), Some e2' when isNullPtrConstant e2' -> t3
| TPtr(b2, _), TPtr(TVoid _ as b3, _), _
| TPtr(TVoid _ as b2, _), TPtr(b3, _), _ ->
let a2 = typeAttrsOuter b2 in
let a3 = typeAttrsOuter b3 in
let (q2, _) = partitionQualifierAttributes a2 in
let (q3, _) = partitionQualifierAttributes a3 in
let q = cabsAddAttributes q2 q3 in
TPtr (TVoid q, [])
| TPtr _, TPtr _, _ when Util.equals (typeSig t2) (typeSig t3) -> t2
| TPtr _, TInt _, _ -> t2 (* most likely comparison with int constant 0, if it isn't it would not be valid C *)
| TInt _, TPtr _, _ -> t3 (* most likely comparison with int constant 0, if it isn't it would not be valid C *)
| TPtr _, TInt _, _ -> t2 (* not "null pointer constant", not allowed by standard, works in gcc/clang with warning *)
| TInt _, TPtr _, _ -> t3 (* not "null pointer constant", not allowed by standard, works in gcc/clang with warning *)

(* When we compare two pointers of different type, we combine them
* using the same algorithm when combining multiple declarations of
* a global *)
| (TPtr _) as t2', (TPtr _ as t3'), _ -> begin
try combineTypes CombineOther t2' t3'
| TPtr (b2, _), TPtr (b3, _), _ -> begin
try
let a2 = typeAttrsOuter b2 in
let a3 = typeAttrsOuter b3 in
let (q2, a2') = partitionQualifierAttributes a2 in
let (q3, a3') = partitionQualifierAttributes a3 in
let b = combineTypes CombineOther (setTypeAttrs b2 a2') (setTypeAttrs b2 a3') in
let q = cabsAddAttributes q2 q3 in
TPtr (cabsTypeAddAttributes q b, [])
with Failure msg -> begin
ignore (warn "A.QUESTION: %a does not match %a (%s)"
d_type (unrollType t2) d_type (unrollType t3) msg);
Expand Down Expand Up @@ -2443,6 +2462,7 @@ let rec doSpecList (suggestedAnonName: string) (* This string will be part of
| [A.Tfloat128] -> TFloat(FLongDouble, []) (* TODO: Correct? *)

(* Now the other type specifiers *)
| [A.Tdefault] -> E.s (error "Default outside generic associations")
| [A.Tnamed n] -> begin
if n = "__builtin_va_list" &&
!Machdep.theMachine.Machdep.__builtin_va_list then begin
Expand Down Expand Up @@ -2629,7 +2649,7 @@ let rec doSpecList (suggestedAnonName: string) (* This string will be part of
and convertCVtoAttr (src: A.cvspec list) : A.attribute list =
match src with
| [] -> []
| CV_CONST :: tl -> ("const",[]) :: (convertCVtoAttr tl)
| CV_CONST :: tl -> ("const",[]) :: ("pconst",[]) :: (convertCVtoAttr tl)
| CV_VOLATILE :: tl -> ("volatile",[]) :: (convertCVtoAttr tl)
| CV_RESTRICT :: tl -> ("restrict",[]) :: (convertCVtoAttr tl)
| CV_COMPLEX :: tl -> ("complex",[]) :: (convertCVtoAttr tl)
Expand Down Expand Up @@ -4798,6 +4818,35 @@ 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 (e, al) ->
let is_default = function
| ([SpecType Tdefault], JUSTBASE) -> true (* exactly matches cparser *)
| _ -> false
in
let (al_default, al_nondefault) = List.partition (fun (at, _) -> is_default at) al in

let typ_compatible t1 t2 =
match combineTypes CombineOther t1 t2 with (* combineTypes does "compatible types" check *)
| _ -> true
| exception (Failure _) -> false
in
let (_, _, e_typ) = doExp false e (AExp None) in (* doExp with AExp handles array and function types for "lvalue conversions" (AType would not!) *)
let e_typ = removeOuterQualifierAttributes e_typ in (* removeOuterQualifierAttributes handles qualifiers for "lvalue conversions" *)
let al_compatible = List.filter (fun ((ast, adt), _) -> typ_compatible e_typ (doOnlyType ast adt)) al_nondefault in

(* TODO: error when multiple compatible associations or defaults even when unused? *)

begin match al_compatible with
| [(_, ae)] -> doExp false ae (AExp None)
| [] ->
begin match al_default with
| [(_, ae)] -> doExp false ae (AExp None)
| [] -> E.s (error "No compatible associations or default in generic")
| _ -> E.s (error "Multiple defaults in generic")
end
| _ -> E.s (error "Multiple compatible associations in generic")
end

with e when continueOnError -> begin
(*ignore (E.log "error in doExp (%s)" (Printexc.to_string e));*)
E.hadErrors := true;
Expand Down
11 changes: 11 additions & 0 deletions src/frontc/cabsvisit.ml
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,17 @@ and childrenExpression vis e =
let b' = visitCabsBlock vis b in
if b' != b then GNU_BODY b' else e
| EXPR_PATTERN _ -> e
| GENERIC (e1, al) ->
let e1' = ve e1 in
let al' = mapNoCopy (fun (((ast, adt), ae) as a) ->
let ast' = visitCabsSpecifier vis ast in
let adt' = visitCabsDeclType vis false adt in
let ae' = ve ae in
if ast' != ast || adt' != adt || ae' != ae then ((ast', adt'), ae') else a
) al
in
if e1' != e1 || al' != al then GENERIC (e1', al') else e


and visitCabsInitExpression vis (ie: init_expression) : init_expression =
doVisit vis vis#vinitexpr childrenInitExpression ie
Expand Down
1 change: 1 addition & 0 deletions src/frontc/clexer.mll
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,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
Expand Down
Loading