summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--clang/lib/AST/Type.cpp6
-rw-r--r--clang/lib/Sema/SemaCast.cpp11
-rw-r--r--clang/test/SemaCXX/enum.cpp14
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
OpenPOWER on IntegriCloud