Hi,
On 08/08/2014 03:55 PM, Jason Merrill wrote:
On 08/08/2014 06:03 AM, Paolo Carlini wrote:
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.
Makes sense.
But it occurs to me that rather than handle the enum situation
specially, maybe we want to give a narrowing error for a constant
value even with -Wno-narrowing, since in that case we know that
there's a problem; the problematic cases that I added -Wno-narrowing
for are non-constant expressions.
Ah, nice idea, that certainly helps a lot, consistency-wise.
Thus I'm finishing testing the below. I considered sending you a version
with a permerror instead of an error, but again, at the end of
build_enumerator we have an error.
Thanks!
Paolo.
/////////////////////
2014-08-08 Paolo Carlini <paolo.carl...@oracle.com>
* doc/invoke.texi ([Wnarrowing]): Update for errors 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 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 instead of warnings.
* g++.dg/cpp0x/enum29.C: Adjust.
* g++.dg/cpp0x/initlist55.C: Likewise.
Index: cp/call.c
===================================================================
--- cp/call.c (revision 213754)
+++ 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: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h (revision 213754)
+++ 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: cp/semantics.c
===================================================================
--- cp/semantics.c (revision 213754)
+++ 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: cp/typeck2.c
===================================================================
--- cp/typeck2.c (revision 213754)
+++ 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,10 @@ 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 +919,17 @@ 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 (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: doc/invoke.texi
===================================================================
--- doc/invoke.texi (revision 213754)
+++ doc/invoke.texi (working copy)
@@ -2622,10 +2622,7 @@ 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}, the diagnostic becomes an error.
@item -Wnoexcept @r{(C++ and Objective-C++ only)}
@opindex Wnoexcept
Index: testsuite/g++.dg/cpp0x/Wnarrowing1.C
===================================================================
--- testsuite/g++.dg/cpp0x/Wnarrowing1.C (revision 213754)
+++ testsuite/g++.dg/cpp0x/Wnarrowing1.C (working copy)
@@ -1,6 +1,5 @@
// PR c++/53159
// { dg-do compile { target c++11 } }
-// { dg-options "-Wnarrowing -Wno-overflow" }
struct X
{
@@ -9,10 +8,10 @@ struct X
int f() { return __INT_MAX__; }
-signed char a { __INT_MAX__ }; // { dg-warning "narrowing conversion" }
-signed char b { f() }; // { dg-warning "narrowing conversion" }
-signed char c { X{} }; // { dg-warning "narrowing conversion" }
+signed char a { __INT_MAX__ }; // { dg-error "narrowing conversion" }
+signed char b { f() }; // { dg-error "narrowing conversion" }
+signed char c { X{} }; // { dg-error "narrowing conversion" }
-signed char ar[] { __INT_MAX__ }; // { dg-warning "narrowing conversion" }
-signed char br[] { f() }; // { dg-warning "narrowing conversion" }
-signed char cr[] { X{} }; // { dg-warning "narrowing conversion" }
+signed char ar[] { __INT_MAX__ }; // { dg-error "narrowing conversion" }
+signed char br[] { f() }; // { dg-error "narrowing conversion" }
+signed char cr[] { X{} }; // { dg-error "narrowing conversion" }
Index: testsuite/g++.dg/cpp0x/enum29.C
===================================================================
--- testsuite/g++.dg/cpp0x/enum29.C (revision 213754)
+++ 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: testsuite/g++.dg/cpp0x/initlist55.C
===================================================================
--- testsuite/g++.dg/cpp0x/initlist55.C (revision 213754)
+++ testsuite/g++.dg/cpp0x/initlist55.C (working copy)
@@ -3,4 +3,4 @@
// { dg-options "-pedantic-errors -Wno-narrowing" }
int i;
-float d = { i };
+float d = { i }; // { dg-error "narrowing" }