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