Scoped enumerations should not be treated as integer types (in the C

sense). Fixes <rdar://problem/9366066> by eliminating an inconsistency
between C++ overloading (which handled scoped enumerations correctly)
and C binary operator type-checking (which didn't).

llvm-svn: 130924
This commit is contained in:
Douglas Gregor 2011-05-05 16:13:52 +00:00
parent 951471482c
commit 21673c4e7e
2 changed files with 13 additions and 3 deletions

View File

@ -517,7 +517,7 @@ bool Type::isIntegerType() const {
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
// Incomplete enum types are not treated as integer types.
// FIXME: In C++, enum types are never integer types.
return ET->getDecl()->isComplete();
return ET->getDecl()->isComplete() && !ET->getDecl()->isScoped();
return false;
}
@ -641,7 +641,7 @@ bool Type::isSignedIntegerType() const {
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) {
// Incomplete enum types are not treated as integer types.
// FIXME: In C++, enum types are never integer types.
if (ET->getDecl()->isComplete())
if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped())
return ET->getDecl()->getIntegerType()->isSignedIntegerType();
}
@ -667,7 +667,7 @@ bool Type::isUnsignedIntegerType() const {
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) {
// Incomplete enum types are not treated as integer types.
// FIXME: In C++, enum types are never integer types.
if (ET->getDecl()->isComplete())
if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped())
return ET->getDecl()->getIntegerType()->isUnsignedIntegerType();
}

View File

@ -109,3 +109,13 @@ void PR9333() {
scoped_enum e = scoped_enum::yes;
if (e == scoped_enum::no) { }
}
// <rdar://problem/9366066>
namespace rdar9366066 {
enum class X : unsigned { value };
void f(X x) {
x % X::value; // expected-error{{invalid operands to binary expression ('rdar9366066::X' and 'rdar9366066::X')}}
x % 8; // expected-error{{invalid operands to binary expression ('rdar9366066::X' and 'int')}}
}
}