Re: [PING] [C++ Patch] PR 82307

2017-10-23 Thread Nathan Sidwell

On 10/23/2017 09:15 AM, Paolo Carlini wrote:

Hi,

following up to a short off-line exchange with Nathan, I'm sending a 
reworked patch which - among other things - avoids regressing on the 
second testcase (cpp0x/enum36.C). Tested x86_64-linux.


ok, thanks!

nathan


--
Nathan Sidwell


Re: [PING] [C++ Patch] PR 82307

2017-10-23 Thread Paolo Carlini

Hi,

following up to a short off-line exchange with Nathan, I'm sending a 
reworked patch which - among other things - avoids regressing on the 
second testcase (cpp0x/enum36.C). Tested x86_64-linux.


Thanks,
Paolo.


/cp
2017-10-23  Mukesh Kapoor  
Paolo Carlini  

PR c++/82307
* cvt.c (type_promotes_to): Implement C++17, 7.6/4, about unscoped
enumeration type whose underlying type is fixed.

/testsuite
2017-10-23  Mukesh Kapoor  
Paolo Carlini  

PR c++/82307
* g++.dg/cpp0x/enum35.C: New.
* g++.dg/cpp0x/enum36.C: Likewise.
Index: cp/cvt.c
===
--- cp/cvt.c(revision 254005)
+++ cp/cvt.c(working copy)
@@ -1834,12 +1834,27 @@ type_promotes_to (tree type)
   || type == char32_type_node
   || type == wchar_type_node)
 {
+  tree prom = type;
+
+  if (TREE_CODE (type) == ENUMERAL_TYPE)
+   {
+ prom = ENUM_UNDERLYING_TYPE (prom);
+ if (!ENUM_IS_SCOPED (type)
+ && ENUM_FIXED_UNDERLYING_TYPE_P (type))
+   {
+ /* ISO C++17, 7.6/4.  A prvalue of an unscoped enumeration type
+whose underlying type is fixed (10.2) can be converted to a
+prvalue of its underlying type. Moreover, if integral promotion
+can be applied to its underlying type, a prvalue of an unscoped
+enumeration type whose underlying type is fixed can also be 
+converted to a prvalue of the promoted underlying type.  */
+ return type_promotes_to (prom);
+   }
+   }
+
   int precision = MAX (TYPE_PRECISION (type),
   TYPE_PRECISION (integer_type_node));
   tree totype = c_common_type_for_size (precision, 0);
-  tree prom = type;
-  if (TREE_CODE (prom) == ENUMERAL_TYPE)
-   prom = ENUM_UNDERLYING_TYPE (prom);
   if (TYPE_UNSIGNED (prom)
  && ! int_fits_type_p (TYPE_MAX_VALUE (prom), totype))
prom = c_common_type_for_size (precision, 1);
Index: testsuite/g++.dg/cpp0x/enum35.C
===
--- testsuite/g++.dg/cpp0x/enum35.C (nonexistent)
+++ testsuite/g++.dg/cpp0x/enum35.C (working copy)
@@ -0,0 +1,14 @@
+// PR c++/82307
+// { dg-do run { target c++11 } }
+
+#include 
+
+enum : unsigned long long { VAL };
+
+bool foo (unsigned long long) { return true; }
+bool foo (int) { return false; }
+
+int main()
+{
+  assert (foo(VAL));
+}
Index: testsuite/g++.dg/cpp0x/enum36.C
===
--- testsuite/g++.dg/cpp0x/enum36.C (nonexistent)
+++ testsuite/g++.dg/cpp0x/enum36.C (working copy)
@@ -0,0 +1,14 @@
+// PR c++/82307
+// { dg-do run { target c++11 } }
+
+#include 
+
+enum : short { VAL };
+
+bool foo (int) { return true; }
+bool foo (unsigned long long) { return false; }
+
+int main()
+{
+  assert (foo (VAL));
+}


Re: [PING] [C++ Patch] PR 82307

2017-10-18 Thread Mukesh Kapoor
The bug happens only for enum types with a fixed underlying type. The 
existing code tries to create another type based on it's precision by 
calling c_common_type_for_size(). For the precision value of an unsigned 
long long type, the call to c_common_type_for_size() returns an unsigned 
long type and this causes compilation errors later on. The fix is to 
simply use the fixed underlying type of the enum instead of creating a 
new one.


Mukesh

On 10/18/2017 1:10 PM, Nathan Sidwell wrote:

On 10/18/2017 12:17 PM, Mukesh Kapoor wrote:

On 10/9/2017 12:20 PM, Mukesh Kapoor wrote:

Hi,

This patch fixes https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82307.
For an unscoped enum with a fixed underlying type, the function 
type_promotes_to() does not always return the same type as the 
underlying type. The fix is to use the underlying type of the enum 
instead of creating a new one by calling c_common_type_for_size().



The diff looks wrong.  Just before the changed piece it (attempts to) 
deal with enum types.  Why is that failing?


nathan





Re: [PING] [C++ Patch] PR 82307

2017-10-18 Thread Nathan Sidwell

On 10/18/2017 12:17 PM, Mukesh Kapoor wrote:

On 10/9/2017 12:20 PM, Mukesh Kapoor wrote:

Hi,

This patch fixes https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82307.
For an unscoped enum with a fixed underlying type, the function 
type_promotes_to() does not always return the same type as the 
underlying type. The fix is to use the underlying type of the enum 
instead of creating a new one by calling c_common_type_for_size().



The diff looks wrong.  Just before the changed piece it (attempts to) 
deal with enum types.  Why is that failing?


nathan

--
Nathan Sidwell


Re: [PING] [C++ Patch] PR 82307

2017-10-18 Thread Mukesh Kapoor

On 10/9/2017 12:20 PM, Mukesh Kapoor wrote:

Hi,

This patch fixes https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82307.
For an unscoped enum with a fixed underlying type, the function 
type_promotes_to() does not always return the same type as the 
underlying type. The fix is to use the underlying type of the enum 
instead of creating a new one by calling c_common_type_for_size().


Bootstrapped and tested with 'make check' on x86_64-linux. New test 
case added.


Mukesh





[C++ Patch] PR 82307

2017-10-09 Thread Mukesh Kapoor

Hi,

This patch fixes https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82307.
For an unscoped enum with a fixed underlying type, the function 
type_promotes_to() does not always return the same type as the 
underlying type. The fix is to use the underlying type of the enum 
instead of creating a new one by calling c_common_type_for_size().


Bootstrapped and tested with 'make check' on x86_64-linux. New test case 
added.


Mukesh

Index: gcc/cp/cvt.c
===
--- gcc/cp/cvt.c(revision 253551)
+++ gcc/cp/cvt.c(working copy)
@@ -1854,11 +1854,16 @@
   tree prom = type;
   if (TREE_CODE (prom) == ENUMERAL_TYPE)
prom = ENUM_UNDERLYING_TYPE (prom);
-  if (TYPE_UNSIGNED (prom)
- && ! int_fits_type_p (TYPE_MAX_VALUE (prom), totype))
-   prom = c_common_type_for_size (precision, 1);
-  else
-   prom = totype;
+  // If an unscoped enum has fixed underlying type,
+  // use that type (bug 82307)
+  if (!ENUM_FIXED_UNDERLYING_TYPE_P (type) || SCOPED_ENUM_P (type))
+   {
+ if (TYPE_UNSIGNED (prom)
+ && ! int_fits_type_p (TYPE_MAX_VALUE (prom), totype))
+   prom = c_common_type_for_size (precision, 1);
+ else
+   prom = totype;
+   }
   if (SCOPED_ENUM_P (type))
{
  if (abi_version_crosses (6)
Index: gcc/testsuite/g++.dg/cpp0x/pr_82307.C
===
--- gcc/testsuite/g++.dg/cpp0x/pr_82307.C   (revision 0)
+++ gcc/testsuite/g++.dg/cpp0x/pr_82307.C   (working copy)
@@ -0,0 +1,24 @@
+// PR c++/82307
+// { dg-do compile { target c++11 } }
+
+#include 
+#include 
+
+enum : unsigned long long { VAL };
+
+const char* foo( unsigned long long )
+{
+  return "unsigned long long";
+}
+
+const char* foo( int )
+{
+  return "int";
+}
+
+int main( void )
+{
+  if (strcmp(foo(VAL), "unsigned long long") != 0)
+abort();
+}
+