diff options
author | Manuel López-Ibáñez <manu@gcc.gnu.org> | 2008-08-09 00:30:41 +0000 |
---|---|---|
committer | Manuel López-Ibáñez <manu@gcc.gnu.org> | 2008-08-09 00:30:41 +0000 |
commit | b13e752fd50ce3c0084d0e4392280d8290bf1c3d (patch) | |
tree | 1a4421253e39d8a04c7c0e7d3bf749563fa6341d /gcc | |
parent | 97679e5f65218a9f6cef39b194f7845bba8bf90b (diff) | |
download | gcc-b13e752fd50ce3c0084d0e4392280d8290bf1c3d.zip gcc-b13e752fd50ce3c0084d0e4392280d8290bf1c3d.tar.gz gcc-b13e752fd50ce3c0084d0e4392280d8290bf1c3d.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 36 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/pr12242.C | 57 |
4 files changed, 93 insertions, 10 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8fd8842..bd8821c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 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 diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 3ee3ba7..8e26927 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -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)) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2603ac2..31b271e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 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. diff --git a/gcc/testsuite/g++.dg/warn/pr12242.C b/gcc/testsuite/g++.dg/warn/pr12242.C new file mode 100644 index 0000000..db4cc10 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/pr12242.C @@ -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" } + ); +} + |