Skip to content

Commit 21673c4

Browse files
committed
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
1 parent 9514714 commit 21673c4

File tree

2 files changed

+13
-3
lines changed

2 files changed

+13
-3
lines changed

clang/lib/AST/Type.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ bool Type::isIntegerType() const {
517517
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
518518
// Incomplete enum types are not treated as integer types.
519519
// FIXME: In C++, enum types are never integer types.
520-
return ET->getDecl()->isComplete();
520+
return ET->getDecl()->isComplete() && !ET->getDecl()->isScoped();
521521
return false;
522522
}
523523

@@ -641,7 +641,7 @@ bool Type::isSignedIntegerType() const {
641641
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) {
642642
// Incomplete enum types are not treated as integer types.
643643
// FIXME: In C++, enum types are never integer types.
644-
if (ET->getDecl()->isComplete())
644+
if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped())
645645
return ET->getDecl()->getIntegerType()->isSignedIntegerType();
646646
}
647647

@@ -667,7 +667,7 @@ bool Type::isUnsignedIntegerType() const {
667667
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) {
668668
// Incomplete enum types are not treated as integer types.
669669
// FIXME: In C++, enum types are never integer types.
670-
if (ET->getDecl()->isComplete())
670+
if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped())
671671
return ET->getDecl()->getIntegerType()->isUnsignedIntegerType();
672672
}
673673

clang/test/SemaCXX/enum-scoped.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,13 @@ void PR9333() {
109109
scoped_enum e = scoped_enum::yes;
110110
if (e == scoped_enum::no) { }
111111
}
112+
113+
// <rdar://problem/9366066>
114+
namespace rdar9366066 {
115+
enum class X : unsigned { value };
116+
117+
void f(X x) {
118+
x % X::value; // expected-error{{invalid operands to binary expression ('rdar9366066::X' and 'rdar9366066::X')}}
119+
x % 8; // expected-error{{invalid operands to binary expression ('rdar9366066::X' and 'int')}}
120+
}
121+
}

0 commit comments

Comments
 (0)