r210723 - PR19966: don't crash/assert when __underlying_type is applied to an incomplete

Richard Smith richard-llvm at metafoo.co.uk
Wed Jun 11 17:01:45 PDT 2014


Author: rsmith
Date: Wed Jun 11 19:01:45 2014
New Revision: 210723

URL: http://llvm.org/viewvc/llvm-project?rev=210723&view=rev
Log:
PR19966: don't crash/assert when __underlying_type is applied to an incomplete
enumeration type. I've also filed a LWG issue pointing out that this should be
ill-formed.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/test/SemaCXX/underlying_type.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=210723&r1=210722&r2=210723&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Jun 11 19:01:45 2014
@@ -1686,6 +1686,8 @@ def err_enum_class_reference : Error<
   "not 'enum class'">;
 def err_only_enums_have_underlying_types : Error<
   "only enumeration types have underlying types">;
+def err_underlying_type_of_incomplete_enum : Error<
+  "cannot determine underlying type of incomplete enumeration type %0">;
 
 // C++11 delegating constructors
 def err_delegating_ctor : Error<

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=210723&r1=210722&r2=210723&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Wed Jun 11 19:01:45 2014
@@ -5557,12 +5557,23 @@ QualType Sema::BuildUnaryTransformType(Q
     } else {
       QualType Underlying = BaseType;
       if (!BaseType->isDependentType()) {
+        // The enum could be incomplete if we're parsing its definition or
+        // recovering from an error.
+        NamedDecl *FwdDecl = nullptr;
+        if (BaseType->isIncompleteType(&FwdDecl)) {
+          Diag(Loc, diag::err_underlying_type_of_incomplete_enum) << BaseType;
+          Diag(FwdDecl->getLocation(), diag::note_forward_declaration) << FwdDecl;
+          return QualType();
+        }
+
         EnumDecl *ED = BaseType->getAs<EnumType>()->getDecl();
         assert(ED && "EnumType has no EnumDecl");
+
         DiagnoseUseOfDecl(ED, Loc);
+
         Underlying = ED->getIntegerType();
+        assert(!Underlying.isNull());
       }
-      assert(!Underlying.isNull());
       return Context.getUnaryTransformType(BaseType, Underlying,
                                         UnaryTransformType::EnumUnderlyingType);
     }

Modified: cfe/trunk/test/SemaCXX/underlying_type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/underlying_type.cpp?rev=210723&r1=210722&r2=210723&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/underlying_type.cpp (original)
+++ cfe/trunk/test/SemaCXX/underlying_type.cpp Wed Jun 11 19:01:45 2014
@@ -41,3 +41,17 @@ enum class foo : uint { bar };
  
 static_assert(is_same_type<underlying_type<foo>::type, unsigned>::value,
               "foo has the wrong underlying type");
+
+namespace PR19966 {
+  void PR19966(enum Invalid) { // expected-note 2{{forward declaration of}}
+    // expected-error at -1 {{ISO C++ forbids forward references to 'enum'}}
+    // expected-error at -2 {{variable has incomplete type}}
+    __underlying_type(Invalid) dont_crash;
+    // expected-error at -1 {{cannot determine underlying type of incomplete enumeration type 'PR19966::Invalid'}}
+  }
+  enum E { // expected-note {{forward declaration of 'E'}}
+    a = (__underlying_type(E)){}
+    // expected-error at -1 {{cannot determine underlying type of incomplete enumeration type 'PR19966::E'}}
+    // expected-error at -2 {{constant expression}}
+  };
+}





More information about the cfe-commits mailing list