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.
2014-08-08 Paolo Carlini <paolo.carl...@oracle.com>
* doc/invoke.texi ([Wnarrowing]): Update for non-constants in C++11.
/cp
2014-08-08 Paolo Carlini <paolo.carl...@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.carl...@oracle.com>
* g++.dg/cpp0x/Wnarrowing1.C: Adjust for errors.
* g++.dg/cpp0x/enum29.C: Adjust.
/libstdc++-v3
2014-08-08 Paolo Carlini <paolo.carl...@oracle.com>
* include/ext/pod_char_traits.h (char_traits<__gnu_cxx::
character<_Value, _Int, _St> >::eof): Fix vs narrowing conversion.
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;
}