... I'm attaching some code accompanying my blabber. Note - in fact I noticed this some days ago - that probably the idea of passing complain to check_narrowing is good anyway, otherwise we have a function emitting unconditional warnings called by functions which have a tsubst_flags_t.

Paolo.

/////////////
Index: call.c
===================================================================
--- call.c      (revision 213752)
+++ call.c      (working copy)
@@ -6252,7 +6252,7 @@ convert_like_real (conversion *convs, tree expr, t
            if (sub == error_mark_node)
              return sub;
            if (!BRACE_ENCLOSED_INITIALIZER_P (val))
-             check_narrowing (TREE_TYPE (sub), val);
+             check_narrowing (TREE_TYPE (sub), val, complain);
            CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_ctor), NULL_TREE, 
sub);
            if (!TREE_CONSTANT (sub))
              TREE_CONSTANT (new_ctor) = false;
@@ -6480,10 +6480,11 @@ convert_like_real (conversion *convs, tree expr, t
       break;
     }
 
+  int error_count = errorcount;
   if (convs->check_narrowing)
-    check_narrowing (totype, expr);
+    check_narrowing (totype, expr, complain);
 
-  if (issue_conversion_warnings)
+  if (issue_conversion_warnings && errorcount == error_count)
     expr = cp_convert_and_check (totype, expr, complain);
   else
     expr = cp_convert (totype, expr, complain);
Index: cp-tree.h
===================================================================
--- cp-tree.h   (revision 213752)
+++ cp-tree.h   (working copy)
@@ -4331,6 +4331,7 @@ enum tsubst_flags {
                                    for calls in decltype (5.2.2/11).  */
   tf_partial = 1 << 8,          /* Doing initial explicit argument
                                    substitution in fn_type_unification.  */
+  tf_enum = 1 << 9,              /* */
   /* Convenient substitution flags combinations.  */
   tf_warning_or_error = tf_warning | tf_error
 };
@@ -6214,7 +6215,7 @@ extern int abstract_virtuals_error_sfinae (tree, t
 extern int abstract_virtuals_error_sfinae      (abstract_class_use, tree, 
tsubst_flags_t);
 
 extern tree store_init_value                   (tree, tree, vec<tree, 
va_gc>**, int);
-extern void check_narrowing                    (tree, tree);
+extern void check_narrowing                    (tree, tree, tsubst_flags_t);
 extern tree digest_init                                (tree, tree, 
tsubst_flags_t);
 extern tree digest_init_flags                  (tree, tree, int);
 extern tree digest_nsdmi_init                  (tree, tree);
Index: decl.c
===================================================================
--- decl.c      (revision 213752)
+++ decl.c      (working copy)
@@ -12974,7 +12974,8 @@ build_enumerator (tree name, tree value, tree enum
            }
          else if (! INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (value)))
            value = perform_implicit_conversion_flags
-             (ENUM_UNDERLYING_TYPE (enumtype), value, tf_warning_or_error,
+             (ENUM_UNDERLYING_TYPE (enumtype), value,
+              tf_warning_or_error | tf_enum,
               LOOKUP_IMPLICIT | LOOKUP_NO_NARROWING);
 
          if (value == error_mark_node)
Index: semantics.c
===================================================================
--- semantics.c (revision 213752)
+++ semantics.c (working copy)
@@ -2598,7 +2598,7 @@ finish_compound_literal (tree type, tree compound_
   if (SCALAR_TYPE_P (type)
       && !BRACE_ENCLOSED_INITIALIZER_P (compound_literal)
       && (complain & tf_warning_or_error))
-    check_narrowing (type, compound_literal);
+    check_narrowing (type, compound_literal, complain);
   if (TREE_CODE (type) == ARRAY_TYPE
       && TYPE_DOMAIN (type) == NULL_TREE)
     {
Index: typeck2.c
===================================================================
--- typeck2.c   (revision 213752)
+++ typeck2.c   (working copy)
@@ -845,13 +845,15 @@ store_init_value (tree decl, tree init, vec<tree,
 /* Give errors about narrowing conversions within { }.  */
 
 void
-check_narrowing (tree type, tree init)
+check_narrowing (tree type, tree init, tsubst_flags_t complain)
 {
   tree ftype = unlowered_expr_type (init);
   bool ok = true;
   REAL_VALUE_TYPE d;
 
-  if (!warn_narrowing || !ARITHMETIC_TYPE_P (type))
+  if (!(complain & tf_warning_or_error)
+      || (!warn_narrowing && !(complain & tf_enum))
+      || !ARITHMETIC_TYPE_P (type))
     return;
 
   if (BRACE_ENCLOSED_INITIALIZER_P (init)
@@ -859,9 +861,9 @@ void
     {
       tree elttype = TREE_TYPE (type);
       if (CONSTRUCTOR_NELTS (init) > 0)
-        check_narrowing (elttype, CONSTRUCTOR_ELT (init, 0)->value);
+        check_narrowing (elttype, CONSTRUCTOR_ELT (init, 0)->value, complain);
       if (CONSTRUCTOR_NELTS (init) > 1)
-       check_narrowing (elttype, CONSTRUCTOR_ELT (init, 1)->value);
+       check_narrowing (elttype, CONSTRUCTOR_ELT (init, 1)->value, complain);
       return;
     }
 
@@ -918,9 +920,15 @@ void
   if (!ok)
     {
       if (cxx_dialect >= cxx11)
-       pedwarn (EXPR_LOC_OR_LOC (init, input_location), OPT_Wnarrowing,
-                "narrowing conversion of %qE from %qT to %qT inside { }",
-                init, ftype, type);
+       {
+         if (complain & tf_enum)
+           error ("enumerator value %E is outside the range of underlying "
+                  "type %<%T%>", init, type);
+         else
+           pedwarn (EXPR_LOC_OR_LOC (init, input_location), OPT_Wnarrowing,
+                    "narrowing conversion of %qE from %qT to %qT inside { }",
+                    init, ftype, type);
+       }
       else
        warning_at (EXPR_LOC_OR_LOC (init, input_location), OPT_Wnarrowing,
                    "narrowing conversion of %qE from %qT to %qT inside { } "

Reply via email to