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
parent 97679e5f
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
* cp-tree.h (struct diagnostic_context, struct diagnostic_info):
Delete forward declarations. Check that toplev.h has not been
......
......@@ -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))
{
......
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
* gcc.dg/pr36901-1.c: New.
* gcc.dg/pr36901-3.c: New.
......
// 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" }
);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment