diff --git a/src/kernel_services/plugin_entry_points/kernel.ml b/src/kernel_services/plugin_entry_points/kernel.ml
index 9c4a3b5306acdf51c56a02afc958a2132237bf28..31065775b513da7b9bb861c01a9eeef1b47b9101 100644
--- a/src/kernel_services/plugin_entry_points/kernel.ml
+++ b/src/kernel_services/plugin_entry_points/kernel.ml
@@ -1113,13 +1113,15 @@ module LogicalOperators =
 let () = Parameter_customize.set_group normalisation
 let () = Parameter_customize.do_not_reset_on_copy ()
 module Enums =
-  P.Empty_string
+  P.String
     (struct
       let option_name = "-enums"
       let arg_name = "repr"
+      let default = "gcc-enums"
       let help = 
         "use <repr> to decide how enumerated types should be represented. \
-         -enums help gives the list of available representations"
+         -enums help gives the list of available representations (default: "
+        ^ default ^ ")"
      end)
 let enum_reprs = ["gcc-enums"; "gcc-short-enums"; "int";]
 let () = Enums.set_possible_values ("help"::enum_reprs)
diff --git a/src/plugins/variadic/standard.ml b/src/plugins/variadic/standard.ml
index af4fefa77c6ff1afd14bbe039b0a338210481b10..d5b98d5d1d192291de971216ec7783223cba3101 100644
--- a/src/plugins/variadic/standard.ml
+++ b/src/plugins/variadic/standard.ml
@@ -72,21 +72,35 @@ let is_extended_integer_type t =
   | TNamed (ti, _) -> List.mem ti.tname extended_integer_typenames
   | _ -> false
 
+let integral_rep ikind =
+  Cil.bitsSizeOfInt ikind, Cil.isSigned ikind
+
+let expose t =
+  Cil.type_remove_attributes_for_c_cast (Cil.unrollType t)
+
+(* 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 =
-  let integral_rep ikind =
-    Cil.bitsSizeOfInt ikind, Cil.isSigned ikind
-  and expose t =
-    Cil.type_remove_attributes_for_c_cast (Cil.unrollType t)
-  in
   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
@@ -105,12 +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
-    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
 
 
diff --git a/src/plugins/variadic/tests/known/oracle/printf_wrong_types.res.oracle b/src/plugins/variadic/tests/known/oracle/printf_wrong_types.res.oracle
index 0bb2cd97335e2418ef8ddedeb6cfdbf5ae09c1f9..39f1ae9b900ea71a6413863dd6ced0e450a76c99 100644
--- a/src/plugins/variadic/tests/known/oracle/printf_wrong_types.res.oracle
+++ b/src/plugins/variadic/tests/known/oracle/printf_wrong_types.res.oracle
@@ -69,7 +69,11 @@
 [variadic] tests/known/printf_wrong_types.c:35: 
   Translating call to printf to a call to the specialized version printf_va_15.
 [variadic] tests/known/printf_wrong_types.c:35: Warning: 
-  Incorrect type for argument 2. The argument will be cast from RC (unsigned int) to unsigned int.
+  Possible portability issues with enum type for argument 2 (use -variadic-no-strict to avoid this warning).
+[variadic] tests/known/printf_wrong_types.c:36: 
+  Translating call to printf to a call to the specialized version printf_va_16.
+[variadic] tests/known/printf_wrong_types.c:36: Warning: 
+  Incorrect type for argument 2. The argument will be cast from RC (unsigned int) to int.
 [eva] Analyzing a complete application starting at main
 [eva] Computing initial state
 [eva] Initial state computed
@@ -298,6 +302,19 @@ int printf_va_14(char const * __restrict format, int param0);
  */
 int printf_va_15(char const * __restrict format, unsigned int param0);
 
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_16(char const * __restrict format, int param0);
+
 int main(void)
 {
   int __retres;
@@ -325,6 +342,7 @@ int main(void)
   printf_va_14("%d",(int)string);
   RC rc = OK;
   printf_va_15("%u",rc);
+  printf_va_16("%d",(int)rc);
   __retres = 0;
   return __retres;
 }
@@ -386,6 +404,7 @@ int main(void)
   printf("%d",string);
   RC rc = OK;
   printf("%u",rc);
+  printf("%d",rc);
   __retres = 0;
   return __retres;
 }
@@ -453,6 +472,10 @@ int main(void)
   Incorrect type for argument 2. The argument will be cast from char * to int.
 [variadic] tests/known/printf_wrong_types.c:35: 
   Translating call to printf to a call to the specialized version printf_va_15.
+[variadic] tests/known/printf_wrong_types.c:36: 
+  Translating call to printf to a call to the specialized version printf_va_16.
+[variadic] tests/known/printf_wrong_types.c:36: Warning: 
+  Incorrect type for argument 2. The argument will be cast from RC (unsigned int) to int.
 [eva] Analyzing a complete application starting at main
 [eva] Computing initial state
 [eva] Initial state computed
@@ -681,6 +704,19 @@ int printf_va_14(char const * __restrict format, int param0);
  */
 int printf_va_15(char const * __restrict format, unsigned int param0);
 
+/*@ requires valid_read_string(format);
+    assigns \result, __fc_stdout->__fc_FILE_data;
+    assigns \result
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+    assigns __fc_stdout->__fc_FILE_data
+      \from (indirect: __fc_stdout->__fc_FILE_id),
+            __fc_stdout->__fc_FILE_data, (indirect: *(format + (0 ..))),
+            param0;
+ */
+int printf_va_16(char const * __restrict format, int param0);
+
 int main(void)
 {
   int __retres;
@@ -708,6 +744,7 @@ int main(void)
   printf_va_14("%d",(int)string);
   RC rc = OK;
   printf_va_15("%u",rc);
+  printf_va_16("%d",(int)rc);
   __retres = 0;
   return __retres;
 }
diff --git a/src/plugins/variadic/tests/known/printf_wrong_types.c b/src/plugins/variadic/tests/known/printf_wrong_types.c
index 7b6cdd80e4476bbd983e69f8d3f75d826f34f13a..85cfc9279a4d54d6d5856eb61003896518f8c424 100644
--- a/src/plugins/variadic/tests/known/printf_wrong_types.c
+++ b/src/plugins/variadic/tests/known/printf_wrong_types.c
@@ -32,5 +32,6 @@ int main(){
 
   typedef enum { OK, ERROR } RC;
   RC rc = OK;
-  printf("%u", rc); // Wrong type (in strict mode)
+  printf("%u", rc); // Correct type with '-enums gcc-enums'
+  printf("%d", rc); // Wrong type (in strict mode)
 }