From 15871a53a98ad58df7560490408d0942c6ffbdb9 Mon Sep 17 00:00:00 2001 From: Valentin Perrelle <valentin.perrelle@cea.fr> Date: Mon, 18 Mar 2019 17:53:06 +0100 Subject: [PATCH] [Variadic] Distinguish various cast types --- src/plugins/variadic/standard.ml | 61 ++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/src/plugins/variadic/standard.ml b/src/plugins/variadic/standard.ml index 8f2aac621af..d5b98d5d1d1 100644 --- a/src/plugins/variadic/standard.ml +++ b/src/plugins/variadic/standard.ml @@ -78,24 +78,29 @@ let integral_rep ikind = let expose t = Cil.type_remove_attributes_for_c_cast (Cil.unrollType t) -let is_equivalent_enum given expected = - match expose given, expose expected with - | TInt (i1,a1), TEnum({ekind=i2},a2) - | TEnum({ekind=i1},a1), TInt (i2,a2) -> - integral_rep i1 = integral_rep i2 && - Cil_datatype.Attributes.equal a1 a2 - | _, _ -> false +(* From most permissive to least permissive *) +type castability = Strict (* strictly allowed by the C standard *) + | Tolerated (* tolerated in practice *) + | NonPortable (* non-portable minor deviation *) + | NonStrict (* only allowed in non-strict mode *) + | Never (* never allowed *) let can_cast given expected = match expose given, expose expected with + | t1, t2 when Cil_datatype.Typ.equal t1 t2 -> Strict | (TInt (i1,a1) | TEnum({ekind=i1},a1)), - (TInt (i2,a2) | TEnum({ekind=i2},a2)) - when not (Strict.get ()) || is_extended_integer_type given -> - integral_rep i1 = integral_rep i2 && - Cil_datatype.Attributes.equal a1 a2 - | TPtr _, TPtr _ -> true - | exposed_given, exposed_expected -> - Cil_datatype.Typ.equal exposed_given exposed_expected + (TInt (i2,a2) | TEnum({ekind=i2},a2)) -> + if integral_rep i1 <> integral_rep i2 || + not (Cil_datatype.Attributes.equal a1 a2) then + Never + else if is_extended_integer_type given then + Tolerated + else if i1 = i2 then + NonPortable + else + NonStrict + | TPtr _, TPtr _ -> Strict + | _, _ -> Never let does_fit exp typ = match Cil.constFoldToInt exp, Cil.unrollType typ with @@ -114,18 +119,22 @@ let pretty_typ fmt t = (* cast the i-th argument exp to paramtyp *) let cast_arg i paramtyp exp = let argtyp = Cil.typeOf exp in - if not (can_cast argtyp paramtyp) && not (does_fit exp paramtyp) then - if Strict.get () && is_equivalent_enum argtyp paramtyp then - Self.warning ~current:true - "Possible portability issues with enum type for argument %d \ - (use -variadic-no-strict to avoid this warning)." - (i + 1) - else - Self.warning ~current:true - "Incorrect type for argument %d. \ - The argument will be cast from %a to %a." - (i + 1) - pretty_typ argtyp pretty_typ paramtyp; + if not (does_fit exp paramtyp) then + begin match can_cast argtyp paramtyp with + | Strict | Tolerated -> () + | (NonPortable | NonStrict) when not (Strict.get ()) -> () + | NonPortable -> + Self.warning ~current:true + "Possible portability issues with enum type for argument %d \ + (use -variadic-no-strict to avoid this warning)." + (i + 1) + | NonStrict | Never -> + Self.warning ~current:true + "Incorrect type for argument %d. \ + The argument will be cast from %a to %a." + (i + 1) + pretty_typ argtyp pretty_typ paramtyp + end; Cil.mkCast ~force:false ~e:exp ~newt:paramtyp -- GitLab