[C++ Patch] PR 51312

Paolo Carlini paolo.carlini@oracle.com
Fri Aug 8 10:03:00 GMT 2014


... 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.

/////////////
-------------- next part --------------
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 { } "


More information about the Gcc-patches mailing list