The problem here is that we aren't properly checking what's been passed to
__underlying_type.  It needs an enum, which the code checks, but that enum
mustn't be incomplete, otherwise we crash because ENUM_UNDERLYING_TYPE will
be null until the definition of the enum is completed by finish_enum.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2017-02-22  Marek Polacek  <pola...@redhat.com>

        PR c++/79657
        * semantics.c (finish_underlying_type): Bail out for incomplete enums.

        * g++.dg/ext/underlying_type12.C: New test.

diff --git gcc/cp/semantics.c gcc/cp/semantics.c
index 6ba7c13..67f8b92 100644
--- gcc/cp/semantics.c
+++ gcc/cp/semantics.c
@@ -3838,7 +3838,8 @@ finish_underlying_type (tree type)
       return underlying_type;
     }
 
-  complete_type (type);
+  if (!complete_type_or_else (type, NULL_TREE))
+    return error_mark_node;
 
   if (TREE_CODE (type) != ENUMERAL_TYPE)
     {
diff --git gcc/testsuite/g++.dg/ext/underlying_type12.C 
gcc/testsuite/g++.dg/ext/underlying_type12.C
index e69de29..050ecf2 100644
--- gcc/testsuite/g++.dg/ext/underlying_type12.C
+++ gcc/testsuite/g++.dg/ext/underlying_type12.C
@@ -0,0 +1,6 @@
+// PR c++/79657
+// { dg-do compile { target c++11 } }
+
+enum A { x };
+enum B { a = (__underlying_type (A)) 1 };
+enum C { b = (__underlying_type (C)) 1 }; // { dg-error "incomplete" }

        Marek

Reply via email to