[C++ Patch] PR 51312

Paolo Carlini paolo.carlini@oracle.com
Sat Aug 9 08:52:00 GMT 2014


Hi,

On 08/09/2014 03:33 AM, Jason Merrill wrote:
> On 08/08/2014 07:26 PM, Paolo Carlini wrote:
>> Ok (that seems a latent buglet...). By the way, since I wondered briefly
>> about SFINAE wrt the existing documentation, does what we do in the
>> *non* constant case really matter for SFINAE?
>
> Yes; in unevaluated context, at least.
I see... If you have hints about c++/57460, I would be glad to work on it...
>> Anyway, Ok if testing passes with that change?
>
> Yes, thanks.
Thanks. I'm going to apply the below. Unfortunately the library bit 
turns out to be a bit ugly because int_type can be a pod struct with an 
int data member, or an integer type, possibly unsigned, maybe Jon can 
help with something more elegant.

Thanks again,
Paolo.

PS: in fact we have got quite a few pedwarns protected by complain 
where, when the condition is false, we just go on, we don't immediately 
return error_mark_node, as we would normally do for plain errors. 
Probably I will audit next week.
-------------- next part --------------
2014-08-08  Paolo Carlini  <paolo.carlini@oracle.com>

	* doc/invoke.texi ([Wnarrowing]): Update for non-constants in C++11.

/cp
2014-08-08  Paolo Carlini  <paolo.carlini@oracle.com>

	* typeck2.c (check_narrowing): Add tsubst_flags_t parameter, change
	return type to bool; in C++11 for constants give errors, not pedwarns.
	* cp-tree.h (check_narrowing): Adjust declaration.
	* call.c (convert_like_real): Update calls.
	* semantics.c (finish_compound_literal): Likewise.

/testsuite
2014-08-08  Paolo Carlini  <paolo.carlini@oracle.com>

	* g++.dg/cpp0x/Wnarrowing1.C: Adjust for errors.
	* g++.dg/cpp0x/enum29.C: Adjust.

/libstdc++-v3
2014-08-08  Paolo Carlini  <paolo.carlini@oracle.com>

	* include/ext/pod_char_traits.h (char_traits<__gnu_cxx::
	character<_Value, _Int, _St> >::eof): Fix vs narrowing conversion.
-------------- next part --------------
Index: gcc/cp/call.c
===================================================================
--- gcc/cp/call.c	(revision 213775)
+++ gcc/cp/call.c	(working copy)
@@ -6251,8 +6251,9 @@ convert_like_real (conversion *convs, tree expr, t
 					  1, false, false, complain);
 	    if (sub == error_mark_node)
 	      return sub;
-	    if (!BRACE_ENCLOSED_INITIALIZER_P (val))
-	      check_narrowing (TREE_TYPE (sub), val);
+	    if (!BRACE_ENCLOSED_INITIALIZER_P (val)
+		&& !check_narrowing (TREE_TYPE (sub), val, complain))
+	      return error_mark_node;
 	    CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_ctor), NULL_TREE, sub);
 	    if (!TREE_CONSTANT (sub))
 	      TREE_CONSTANT (new_ctor) = false;
@@ -6480,8 +6481,9 @@ convert_like_real (conversion *convs, tree expr, t
       break;
     }
 
-  if (convs->check_narrowing)
-    check_narrowing (totype, expr);
+  if (convs->check_narrowing
+      && !check_narrowing (totype, expr, complain))
+    return error_mark_node;
 
   if (issue_conversion_warnings)
     expr = cp_convert_and_check (totype, expr, complain);
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 213775)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -6214,7 +6214,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 bool 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: gcc/cp/semantics.c
===================================================================
--- gcc/cp/semantics.c	(revision 213775)
+++ gcc/cp/semantics.c	(working copy)
@@ -2597,8 +2597,8 @@ finish_compound_literal (tree type, tree compound_
   compound_literal = reshape_init (type, compound_literal, complain);
   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))
+    return error_mark_node;
   if (TREE_CODE (type) == ARRAY_TYPE
       && TYPE_DOMAIN (type) == NULL_TREE)
     {
Index: gcc/cp/typeck2.c
===================================================================
--- gcc/cp/typeck2.c	(revision 213775)
+++ gcc/cp/typeck2.c	(working copy)
@@ -842,17 +842,19 @@ store_init_value (tree decl, tree init, vec<tree,
 }
 
 

-/* Give errors about narrowing conversions within { }.  */
+/* Give diagnostic about narrowing conversions within { }.  */
 
-void
-check_narrowing (tree type, tree init)
+bool
+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))
-    return;
+  if (((!warn_narrowing || !(complain & tf_warning))
+       && cxx_dialect == cxx98)
+      || !ARITHMETIC_TYPE_P (type))
+    return ok;
 
   if (BRACE_ENCLOSED_INITIALIZER_P (init)
       && TREE_CODE (type) == COMPLEX_TYPE)
@@ -859,10 +861,12 @@ store_init_value (tree decl, tree init, vec<tree,
     {
       tree elttype = TREE_TYPE (type);
       if (CONSTRUCTOR_NELTS (init) > 0)
-        check_narrowing (elttype, CONSTRUCTOR_ELT (init, 0)->value);
+        ok &= check_narrowing (elttype, CONSTRUCTOR_ELT (init, 0)->value,
+			       complain);
       if (CONSTRUCTOR_NELTS (init) > 1)
-	check_narrowing (elttype, CONSTRUCTOR_ELT (init, 1)->value);
-      return;
+	ok &= check_narrowing (elttype, CONSTRUCTOR_ELT (init, 1)->value,
+			       complain);
+      return ok;
     }
 
   init = maybe_constant_value (fold_non_dependent_expr_sfinae (init, tf_none));
@@ -917,15 +921,27 @@ store_init_value (tree decl, tree init, vec<tree,
 
   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);
-      else
+      if (cxx_dialect == cxx98)
 	warning_at (EXPR_LOC_OR_LOC (init, input_location), OPT_Wnarrowing,
 		    "narrowing conversion of %qE from %qT to %qT inside { } "
 		    "is ill-formed in C++11", init, ftype, type);
+      else if (!TREE_CONSTANT (init))
+	{
+	  if (complain & tf_warning_or_error)
+	    {
+	      pedwarn (EXPR_LOC_OR_LOC (init, input_location), OPT_Wnarrowing,
+		       "narrowing conversion of %qE from %qT to %qT inside { }",
+		       init, ftype, type);
+	      ok = true;
+	    }
+	}
+      else if (complain & tf_error)
+	error_at (EXPR_LOC_OR_LOC (init, input_location),
+		  "narrowing conversion of %qE from %qT to %qT inside { }",
+		  init, ftype, type);
     }
+
+  return cxx_dialect == cxx98 || ok; 
 }
 
 /* Process the initializer INIT for a variable of type TYPE, emitting
Index: gcc/doc/invoke.texi
===================================================================
--- gcc/doc/invoke.texi	(revision 213775)
+++ gcc/doc/invoke.texi	(working copy)
@@ -2622,10 +2622,10 @@ int i = @{ 2.2 @}; // error: narrowing from double
 
 This flag is included in @option{-Wall} and @option{-Wc++11-compat}.
 
-With @option{-std=c++11}, @option{-Wno-narrowing} suppresses the diagnostic
-required by the standard.  Note that this does not affect the meaning
-of well-formed code; narrowing conversions are still considered
-ill-formed in SFINAE context.
+With @option{-std=c++11}, @option{-Wno-narrowing} suppresses for
+non-constants the diagnostic required by the standard.  Note that this
+does not affect the meaning of well-formed code; narrowing conversions
+are still considered ill-formed in SFINAE context.
 
 @item -Wnoexcept @r{(C++ and Objective-C++ only)}
 @opindex Wnoexcept
Index: gcc/testsuite/g++.dg/cpp0x/Wnarrowing1.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/Wnarrowing1.C	(revision 213775)
+++ gcc/testsuite/g++.dg/cpp0x/Wnarrowing1.C	(working copy)
@@ -9,10 +9,10 @@ struct X
 
 int f() { return __INT_MAX__; }
 
-signed char a { __INT_MAX__ };     // { dg-warning "narrowing conversion" }
+signed char a { __INT_MAX__ };     // { dg-error "narrowing conversion" }
 signed char b { f() };             // { dg-warning "narrowing conversion" }
-signed char c { X{} };             // { dg-warning "narrowing conversion" }
+signed char c { X{} };             // { dg-error "narrowing conversion" }
 
-signed char ar[] { __INT_MAX__ };  // { dg-warning "narrowing conversion" }
+signed char ar[] { __INT_MAX__ };  // { dg-error "narrowing conversion" }
 signed char br[] { f() };          // { dg-warning "narrowing conversion" }
-signed char cr[] { X{} };          // { dg-warning "narrowing conversion" }
+signed char cr[] { X{} };          // { dg-error "narrowing conversion" }
Index: gcc/testsuite/g++.dg/cpp0x/enum29.C
===================================================================
--- gcc/testsuite/g++.dg/cpp0x/enum29.C	(revision 213775)
+++ gcc/testsuite/g++.dg/cpp0x/enum29.C	(working copy)
@@ -51,8 +51,6 @@ enum F5 : int { f5 = X5() };
 enum G0 : signed char { g0 = X0() };
 enum G1 : signed char { g1 = X1() };
 enum G2 : signed char { g2 = X2() };  // { dg-error "narrowing" }
-// { dg-warning "overflow" "" { target *-*-* } 53 }
 enum G3 : signed char { g3 = X3() };  // { dg-error "narrowing" }
-// { dg-warning "overflow" "" { target *-*-* } 55 }
 enum G4 : signed char { g4 = X4() };  // { dg-error "narrowing" }
 enum G5 : signed char { g5 = X5() };  // { dg-error "ambiguous" }
Index: libstdc++-v3/include/ext/pod_char_traits.h
===================================================================
--- libstdc++-v3/include/ext/pod_char_traits.h	(revision 213775)
+++ libstdc++-v3/include/ext/pod_char_traits.h	(working copy)
@@ -177,7 +177,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       static int_type
       eof() 
       {
-	int_type __r = { -1 };
+	int_type __r = { static_cast<typename __gnu_cxx::__conditional_type
+			 <std::__is_integer<int_type>::__value,
+			 int_type, int>::__type>(-1) };
 	return __r;
       }
 


More information about the Gcc-patches mailing list