@@ -2461,7 +2461,7 @@ let rec doSpecList (suggestedAnonName: string) (* This string will be part of
24612461 | [A. Tfloat128 ] -> TFloat (FLongDouble , [] ) (* TODO: Correct? *)
24622462
24632463 (* Now the other type specifiers *)
2464- (* | [A.Tdefault] -> TDefault * )
2464+ | [A. Tdefault ] -> E. s (error " Default outside generic associations " )
24652465 | [A. Tnamed n] -> begin
24662466 if n = " __builtin_va_list" &&
24672467 ! Machdep. theMachine.Machdep. __builtin_va_list then begin
@@ -4848,31 +4848,33 @@ and doExp (asconst: bool) (* This expression is used as a constant *)
48484848
48494849 | A. EXPR_PATTERN _ -> E. s (E. bug " EXPR_PATTERN in cabs2cil input" )
48504850
4851- | A. GENERIC (expr , lst ) ->
4852- let get_exp (_ , e , _ ) = e in
4853- let exp = get_exp (doExp false (stripParenLocal expr) (AExp None )) in
4854- let cil_list =
4855- let rec make_cil_list cabs_l cil_l = match cabs_l with
4856- | [] -> cil_l
4857- | (s , e ) :: rest -> make_cil_list rest (((doOnlyType s JUSTBASE ),get_exp (doExp false (stripParenLocal e) (AExp None ))) :: cil_l)
4858- in
4859- make_cil_list lst []
4851+ | A. GENERIC (e , al ) ->
4852+ let is_default = function
4853+ | [SpecType Tdefault ] -> true (* exactly matches cparser *)
4854+ | _ -> false
48604855 in
4861- let exp_typ = typeOf exp in
4862- let default_typ = ref voidType in
4863- let typ =
4864- let rec get_typ lst = match lst with
4865- (* | (TDefault, e ) :: rest -> default_typ := typeOf e ; get_typ rest * )
4866- | (t , e ) :: rest -> if t = exp_typ then typeOf e else get_typ rest
4867- | [] ->
4868- if ! default_typ = voidType then
4869- E. s(error " Controlling expression of generic selection is not compatible with any association" )
4870- else ! default_typ
4871- in
4872- get_typ cil_list
4856+ let (al_default, al_nondefault) = List. partition (fun (at , _ ) -> is_default at) al in
4857+
4858+ let typ_compatible t1 t2 =
4859+ match combineTypes CombineOther t1 t2 with (* combineTypes seems to do "compatible types" check *)
4860+ | _ -> true
4861+ | exception (Failure _ ) -> false
48734862 in
4874- (* finishExp empty (Generic(exp, (cil_list))) typ *)
4875- failwith " TODO"
4863+ let (_, _, e_typ) = doExp false (stripParenLocal e) (AExp None ) in (* TODO: why stripParenLocal? *)
4864+ let al_compatible = List. filter (fun (at , _ ) -> typ_compatible e_typ (doOnlyType at JUSTBASE )) al_nondefault in
4865+
4866+ (* TODO: error when multiple compatible associations or defaults even when unused? *)
4867+
4868+ begin match al_compatible with
4869+ | [(_, ae)] -> doExp false (stripParenLocal ae) (AExp None ) (* TODO: why stripParenLocal? *)
4870+ | [] ->
4871+ begin match al_default with
4872+ | [(_, ae)] -> doExp false (stripParenLocal ae) (AExp None ) (* TODO: why stripParenLocal? *)
4873+ | [] -> E. s (error " No compatible associations or default in generic" )
4874+ | _ -> E. s (error " Multiple defaults in generic" )
4875+ end
4876+ | _ -> E. s (error " Multiple compatible associations in generic" )
4877+ end
48764878
48774879 with e when continueOnError -> begin
48784880 (* ignore (E.log "error in doExp (%s)" (Printexc.to_string e));*)
0 commit comments