* RFA PATCH to get_narrower for c++/48106 (ICE with scoped enum) @ 2011-05-23 15:04 Jason Merrill 2011-05-23 15:46 ` Richard Guenther 0 siblings, 1 reply; 5+ messages in thread From: Jason Merrill @ 2011-05-23 15:04 UTC (permalink / raw) To: gcc-patches List [-- Attachment #1: Type: text/plain, Size: 373 bytes --] C++0x scoped enums don't implicitly convert to an integral type, so we need to be careful about throwing away explicit conversions. In this case, the static_cast<int>(e) creates a NOP_EXPR which get_narrower throws away, but 'e' itself is not a valid argument for &, so we need to replace the NOP_EXPR with a different one. Tested x86_64-pc-linux-gnu. OK for trunk? [-- Attachment #2: 48106.patch --] [-- Type: text/x-patch, Size: 1262 bytes --] commit 8f9cf5d22de2418bdb2ab9cb79ae878f809299ec Author: Jason Merrill <jason@redhat.com> Date: Sun May 22 15:21:19 2011 -0400 PR c++/48106 * tree.c (get_narrower): Handle scoped enum. diff --git a/gcc/testsuite/g++.dg/cpp0x/enum14.C b/gcc/testsuite/g++.dg/cpp0x/enum14.C new file mode 100644 index 0000000..709b201 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/enum14.C @@ -0,0 +1,12 @@ +// PR c++/48106 +// { dg-options -std=c++0x } + +enum class E : char +{ + e +}; + +bool operator&(E e, char m) +{ + return static_cast<int>(e) & m; +} diff --git a/gcc/tree.c b/gcc/tree.c index 3357d84..99402e8 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -8117,6 +8117,17 @@ get_narrower (tree op, int *unsignedp_ptr) win = fold_convert (type, op); } } + else if (TREE_CODE (TREE_TYPE (op)) == ENUMERAL_TYPE + && ENUM_IS_SCOPED (TREE_TYPE (op))) + { + /* C++0x scoped enumerations don't implicitly convert to integral + type, so if we stripped an explicit conversion to a larger type we + need to replace it. */ + tree type = (lang_hooks.types.type_for_size + (TYPE_PRECISION (TREE_TYPE (op)), + TYPE_UNSIGNED (TREE_TYPE (op)))); + win = fold_convert (type, op); + } *unsignedp_ptr = uns; return win; ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: RFA PATCH to get_narrower for c++/48106 (ICE with scoped enum) 2011-05-23 15:04 RFA PATCH to get_narrower for c++/48106 (ICE with scoped enum) Jason Merrill @ 2011-05-23 15:46 ` Richard Guenther 2011-05-23 16:17 ` Jason Merrill 0 siblings, 1 reply; 5+ messages in thread From: Richard Guenther @ 2011-05-23 15:46 UTC (permalink / raw) To: Jason Merrill; +Cc: gcc-patches List On Mon, May 23, 2011 at 4:50 PM, Jason Merrill <jason@redhat.com> wrote: > C++0x scoped enums don't implicitly convert to an integral type, so we need > to be careful about throwing away explicit conversions. In this case, the > static_cast<int>(e) creates a NOP_EXPR which get_narrower throws away, but > 'e' itself is not a valid argument for &, so we need to replace the NOP_EXPR > with a different one. > > Tested x86_64-pc-linux-gnu. OK for trunk? Ok. Though I wonder where you enter folding before you check semantic validity. Thanks, Richard. ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: RFA PATCH to get_narrower for c++/48106 (ICE with scoped enum) 2011-05-23 15:46 ` Richard Guenther @ 2011-05-23 16:17 ` Jason Merrill 2011-05-23 16:25 ` Richard Guenther 2011-05-24 5:33 ` Jason Merrill 0 siblings, 2 replies; 5+ messages in thread From: Jason Merrill @ 2011-05-23 16:17 UTC (permalink / raw) To: Richard Guenther; +Cc: gcc-patches List On 05/23/2011 11:01 AM, Richard Guenther wrote: > Ok. Though I wonder where you enter folding before you check semantic > validity. The problem is in c-common:shorten_binary_op, which uses get_narrower and then calls common_type on the types of the results. There is no common type between a scoped enum and char, so common_type returns NULL_TREE, so we get a SEGV in c_common_signed_or_unsigned_type. Do you think I should change shorten_binary_op instead? Jason ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: RFA PATCH to get_narrower for c++/48106 (ICE with scoped enum) 2011-05-23 16:17 ` Jason Merrill @ 2011-05-23 16:25 ` Richard Guenther 2011-05-24 5:33 ` Jason Merrill 1 sibling, 0 replies; 5+ messages in thread From: Richard Guenther @ 2011-05-23 16:25 UTC (permalink / raw) To: Jason Merrill; +Cc: gcc-patches List On Mon, May 23, 2011 at 5:38 PM, Jason Merrill <jason@redhat.com> wrote: > On 05/23/2011 11:01 AM, Richard Guenther wrote: >> >> Ok. Though I wonder where you enter folding before you check semantic >> validity. > > The problem is in c-common:shorten_binary_op, which uses get_narrower and > then calls common_type on the types of the results. There is no common type > between a scoped enum and char, so common_type returns NULL_TREE, so we get > a SEGV in c_common_signed_or_unsigned_type. > > Do you think I should change shorten_binary_op instead? Yeah, that might constrain it to C family languages. shorten_binary_op is one of our premature optimization things anyway, best to slowly go away ... Richard. > Jason > ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: RFA PATCH to get_narrower for c++/48106 (ICE with scoped enum) 2011-05-23 16:17 ` Jason Merrill 2011-05-23 16:25 ` Richard Guenther @ 2011-05-24 5:33 ` Jason Merrill 1 sibling, 0 replies; 5+ messages in thread From: Jason Merrill @ 2011-05-24 5:33 UTC (permalink / raw) To: Richard Guenther; +Cc: gcc-patches List [-- Attachment #1: Type: text/plain, Size: 158 bytes --] On 05/23/2011 11:38 AM, Jason Merrill wrote: > Do you think I should change shorten_binary_op instead? Thus. Tested x86_64-pc-linux-gnu, applying to trunk. [-- Attachment #2: 48106-2.patch --] [-- Type: text/x-patch, Size: 4003 bytes --] commit 683f3617b323a9d8f62fc5f002d48948eb3b457b Author: Jason Merrill <jason@redhat.com> Date: Mon May 23 11:57:40 2011 -0400 PR c++/48106 * c-common.c (c_common_get_narrower): New. (shorten_binary_op, shorten_compare, warn_for_sign_compare): Use it. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index fef8ded..b822553 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -1765,6 +1765,28 @@ vector_types_convertible_p (const_tree t1, const_tree t2, bool emit_lax_note) return false; } +/* Like tree.c:get_narrower, but retain conversion from C++0x scoped enum + to integral type. */ + +static tree +c_common_get_narrower (tree op, int *unsignedp_ptr) +{ + op = get_narrower (op, unsignedp_ptr); + + if (TREE_CODE (TREE_TYPE (op)) == ENUMERAL_TYPE + && ENUM_IS_SCOPED (TREE_TYPE (op))) + { + /* C++0x scoped enumerations don't implicitly convert to integral + type; if we stripped an explicit conversion to a larger type we + need to replace it so common_type will still work. */ + tree type = (lang_hooks.types.type_for_size + (TYPE_PRECISION (TREE_TYPE (op)), + TYPE_UNSIGNED (TREE_TYPE (op)))); + op = fold_convert (type, op); + } + return op; +} + /* This is a helper function of build_binary_op. For certain operations if both args were extended from the same @@ -1777,7 +1799,8 @@ vector_types_convertible_p (const_tree t1, const_tree t2, bool emit_lax_note) Eg, (short)-1 | (unsigned short)-1 is (int)-1 but calculated in (unsigned short) it would be (unsigned short)-1. */ -tree shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise) +tree +shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise) { int unsigned0, unsigned1; tree arg0, arg1; @@ -1803,8 +1826,8 @@ tree shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise) op0 = convert (result_type, op0); op1 = convert (result_type, op1); - arg0 = get_narrower (op0, &unsigned0); - arg1 = get_narrower (op1, &unsigned1); + arg0 = c_common_get_narrower (op0, &unsigned0); + arg1 = c_common_get_narrower (op1, &unsigned1); /* UNS is 1 if the operation to be done is an unsigned one. */ uns = TYPE_UNSIGNED (result_type); @@ -3301,8 +3324,8 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr, /* Throw away any conversions to wider types already present in the operands. */ - primop0 = get_narrower (op0, &unsignedp0); - primop1 = get_narrower (op1, &unsignedp1); + primop0 = c_common_get_narrower (op0, &unsignedp0); + primop1 = c_common_get_narrower (op1, &unsignedp1); /* If primopN is first sign-extended from primopN's precision to opN's precision, then zero-extended from opN's precision to @@ -9371,16 +9394,16 @@ warn_for_sign_compare (location_t location, have all bits set that are set in the ~ operand when it is extended. */ - op0 = get_narrower (op0, &unsignedp0); - op1 = get_narrower (op1, &unsignedp1); + op0 = c_common_get_narrower (op0, &unsignedp0); + op1 = c_common_get_narrower (op1, &unsignedp1); if ((TREE_CODE (op0) == BIT_NOT_EXPR) ^ (TREE_CODE (op1) == BIT_NOT_EXPR)) { if (TREE_CODE (op0) == BIT_NOT_EXPR) - op0 = get_narrower (TREE_OPERAND (op0, 0), &unsignedp0); + op0 = c_common_get_narrower (TREE_OPERAND (op0, 0), &unsignedp0); if (TREE_CODE (op1) == BIT_NOT_EXPR) - op1 = get_narrower (TREE_OPERAND (op1, 0), &unsignedp1); + op1 = c_common_get_narrower (TREE_OPERAND (op1, 0), &unsignedp1); if (host_integerp (op0, 0) || host_integerp (op1, 0)) { diff --git a/gcc/testsuite/g++.dg/cpp0x/enum14.C b/gcc/testsuite/g++.dg/cpp0x/enum14.C new file mode 100644 index 0000000..709b201 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/enum14.C @@ -0,0 +1,12 @@ +// PR c++/48106 +// { dg-options -std=c++0x } + +enum class E : char +{ + e +}; + +bool operator&(E e, char m) +{ + return static_cast<int>(e) & m; +} ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-05-23 22:46 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2011-05-23 15:04 RFA PATCH to get_narrower for c++/48106 (ICE with scoped enum) Jason Merrill 2011-05-23 15:46 ` Richard Guenther 2011-05-23 16:17 ` Jason Merrill 2011-05-23 16:25 ` Richard Guenther 2011-05-24 5:33 ` Jason Merrill
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).