diff options
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 2 | ||||
-rw-r--r-- | clang/lib/AST/Type.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Sema/SemaCast.cpp | 11 | ||||
-rw-r--r-- | clang/test/SemaCXX/enum.cpp | 14 |
4 files changed, 14 insertions, 19 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 2529f7f7f72..3ffbbed1744 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6679,7 +6679,7 @@ def err_upcast_to_inaccessible_base : Error< def err_bad_dynamic_cast_not_ref_or_ptr : Error< "invalid target type %0 for dynamic_cast; target type must be a reference or pointer type to a defined class">; def err_bad_dynamic_cast_not_class : Error<"%0 is not a class type">; -def err_bad_dynamic_cast_incomplete : Error<"%0 is an incomplete type">; +def err_bad_cast_incomplete : Error<"%0 is an incomplete type">; def err_bad_dynamic_cast_not_ptr : Error<"cannot use dynamic_cast to convert from %0 to %1">; def err_bad_dynamic_cast_not_polymorphic : Error<"%0 is not polymorphic">; diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 85447d682ba..c5ad711d872 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -1860,12 +1860,8 @@ bool Type::isIntegralOrUnscopedEnumerationType() const { } bool Type::isUnscopedEnumerationType() const { - // Check for a complete enum type; incomplete enum types are not properly an - // enumeration type in the sense required here. - // C++0x: However, if the underlying type of the enum is fixed, it is - // considered complete. if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) - return ET->getDecl()->isComplete() && !ET->getDecl()->isScoped(); + return !ET->getDecl()->isScoped(); return false; } diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 741cf638760..d0b9fe12289 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -740,7 +740,7 @@ void CastOperation::CheckDynamicCast() { assert(DestPointer && "Reference to void is not possible"); } else if (DestRecord) { if (Self.RequireCompleteType(OpRange.getBegin(), DestPointee, - diag::err_bad_dynamic_cast_incomplete, + diag::err_bad_cast_incomplete, DestRange)) { SrcExpr = ExprError(); return; @@ -785,7 +785,7 @@ void CastOperation::CheckDynamicCast() { const RecordType *SrcRecord = SrcPointee->getAs<RecordType>(); if (SrcRecord) { if (Self.RequireCompleteType(OpRange.getBegin(), SrcPointee, - diag::err_bad_dynamic_cast_incomplete, + diag::err_bad_cast_incomplete, SrcExpr.get())) { SrcExpr = ExprError(); return; @@ -1182,6 +1182,11 @@ static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, // The same goes for reverse floating point promotion/conversion and // floating-integral conversions. Again, only floating->enum is relevant. if (DestType->isEnumeralType()) { + if (Self.RequireCompleteType(OpRange.getBegin(), DestType, + diag::err_bad_cast_incomplete)) { + SrcExpr = ExprError(); + return TC_Failed; + } if (SrcType->isIntegralOrEnumerationType()) { Kind = CK_IntegralCast; return TC_Success; @@ -1651,7 +1656,7 @@ TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, CastKind &Kind, bool ListInitialization) { if (DestType->isRecordType()) { if (Self.RequireCompleteType(OpRange.getBegin(), DestType, - diag::err_bad_dynamic_cast_incomplete) || + diag::err_bad_cast_incomplete) || Self.RequireNonAbstractType(OpRange.getBegin(), DestType, diag::err_allocation_of_abstract_type)) { msg = 0; diff --git a/clang/test/SemaCXX/enum.cpp b/clang/test/SemaCXX/enum.cpp index 16ebebe31b6..b193a17ebf9 100644 --- a/clang/test/SemaCXX/enum.cpp +++ b/clang/test/SemaCXX/enum.cpp @@ -88,19 +88,13 @@ enum { }; // expected-warning{{declaration does not declare anything}} typedef enum { }; // expected-warning{{typedef requires a name}} // PR7921 -enum PR7921E { - PR7921V = (PR7921E)(123) -#if __cplusplus < 201103L -// expected-error@-2 {{expression is not an integral constant expression}} -#else -// expected-error@-4 {{must have integral or unscoped enumeration type}} -// FIXME: The above diagnostic isn't very good; we should instead complain about the type being incomplete. -#endif +enum PR7921E { // expected-note {{not complete until the closing '}'}} + PR7921V = (PR7921E)(123) // expected-error {{'PR7921E' is an incomplete type}} }; void PR8089() { - enum E; // expected-error{{ISO C++ forbids forward references to 'enum' types}} - int a = (E)3; // expected-error{{cannot initialize a variable of type 'int' with an rvalue of type 'E'}} + enum E; // expected-error{{ISO C++ forbids forward references to 'enum' types}} expected-note {{forward declaration}} + int a = (E)3; // expected-error {{'E' is an incomplete type}} } // This is accepted as a GNU extension. In C++98, there was no provision for |