public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* 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).