re PR c++/12242 (g++ should warn about out-of-range int->enum conversions)

2008-08-09  Manuel Lopez-Ibanez  <manu@gcc.gnu.org>

	PR c++/12242
cp/
	* cvt.c (ocp_convert): Warn for out-of-range conversions to enum.

testsuite/
	* g++.dg/warn/pr12242.C: New.

From-SVN: r138898
This commit is contained in:
Manuel López-Ibáñez 2008-08-09 00:30:41 +00:00
parent 97679e5f65
commit b13e752fd5
4 changed files with 93 additions and 10 deletions

View file

@ -1,3 +1,8 @@
2008-08-09 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
PR c++/12242
* cvt.c (ocp_convert): Warn for out-of-range conversions to enum.
2008-08-09 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
PR 36901

View file

@ -638,19 +638,35 @@ ocp_convert (tree type, tree expr, int convtype, int flags)
if (INTEGRAL_CODE_P (code))
{
tree intype = TREE_TYPE (e);
/* enum = enum, enum = int, enum = float, (enum)pointer are all
errors. */
if (TREE_CODE (type) == ENUMERAL_TYPE
&& (((INTEGRAL_OR_ENUMERATION_TYPE_P (intype)
if (TREE_CODE (type) == ENUMERAL_TYPE)
{
/* enum = enum, enum = int, enum = float, (enum)pointer are all
errors. */
if (((INTEGRAL_OR_ENUMERATION_TYPE_P (intype)
|| TREE_CODE (intype) == REAL_TYPE)
&& ! (convtype & CONV_STATIC))
|| TREE_CODE (intype) == POINTER_TYPE))
{
if (flags & LOOKUP_COMPLAIN)
permerror ("conversion from %q#T to %q#T", intype, type);
|| TREE_CODE (intype) == POINTER_TYPE)
{
if (flags & LOOKUP_COMPLAIN)
permerror ("conversion from %q#T to %q#T", intype, type);
if (!flag_permissive)
return error_mark_node;
if (!flag_permissive)
return error_mark_node;
}
/* [expr.static.cast]
8. A value of integral or enumeration type can be explicitly
converted to an enumeration type. The value is unchanged if
the original value is within the range of the enumeration
values. Otherwise, the resulting enumeration value is
unspecified. */
if (TREE_CODE (expr) == INTEGER_CST && !int_fits_type_p (expr, type))
warning (OPT_Wconversion,
"the result of the conversion is unspecified because "
"%qE is outside the range of type %qT",
expr, type);
}
if (MAYBE_CLASS_TYPE_P (intype))
{

View file

@ -1,3 +1,8 @@
2008-08-09 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
PR c++/12242
* g++.dg/warn/pr12242.C: New.
2008-08-09 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
PR 36901

View file

@ -0,0 +1,57 @@
// PR 12242: should warn about out-of-range int->enum conversions
// { dg-do compile }
// { dg-options "-Wconversion -fpermissive" }
enum X { A };
enum Y { B, C, D };
void example ()
{
int i = 5;
X x;
Y y;
x = 10; // { dg-warning "warning: invalid conversion from .int. to .X." }
// { dg-warning "warning:\[^\n\]*unspecified" "" { target *-*-* } 13 }
x = 1; // { dg-warning "warning: invalid conversion from .int. to .X." }
x = C; // { dg-error "error: cannot convert .Y. to .X. in assignment" }
x = D; // { dg-error "error: cannot convert .Y. to .X. in assignment" }
y = A; // { dg-error "error: cannot convert .X. to .Y. in assignment" }
x = y; // { dg-error "error: cannot convert .Y. to .X. in assignment" }
x = i; // { dg-warning "warning: invalid conversion from .int. to .X." }
}
void foo ()
{
X a = static_cast<X> (10); // { dg-warning "warning:\[^\n\]*unspecified" }
X b = static_cast<X> (0);
X c = static_cast<X> (1);
X d = static_cast<X> (2); // { dg-warning "warning:\[^\n\]*unspecified" }
X f = static_cast<X> ((int)A);
X g = static_cast<X> (B);
X h = static_cast<X> (C);
X e = static_cast<X> (D); // { dg-warning "warning\[^\n\]*unspecified" }
}
enum QEvent { x = 42 };
int bar()
{
QEvent x = ( QEvent ) 42000; // { dg-warning "warning\[^\n\]*unspecified" }
return ( int ) x;
}
enum W {a,b,c};
enum Z {d,e,f,g};
void bazz (int, int, int, int);
void baz() {
int three = 3;
int four = 4;
bazz (
W(three),
W(3),
Z(four),
Z(4) // { dg-warning "warning\[^\n\]*unspecified" }
);
}