зеркало из https://github.com/microsoft/clang-1.git
Clean up enum constants so that they're finally sane. Fixes PR3173 and a
recently introduced crash. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91070 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
548e60efea
Коммит
29a7f3342c
|
@ -4522,7 +4522,7 @@ unsigned ASTContext::getIntWidth(QualType T) {
|
|||
return FWIT->getWidth();
|
||||
}
|
||||
if (EnumType *ET = dyn_cast<EnumType>(T))
|
||||
T = ET->getDecl()->getPromotionType();
|
||||
T = ET->getDecl()->getIntegerType();
|
||||
// For builtin types, just use the standard type sizing method
|
||||
return (unsigned)getTypeSize(T);
|
||||
}
|
||||
|
|
|
@ -848,16 +848,8 @@ static bool EvaluateInteger(const Expr* E, APSInt &Result, EvalInfo &Info) {
|
|||
|
||||
bool IntExprEvaluator::CheckReferencedDecl(const Expr* E, const Decl* D) {
|
||||
// Enums are integer constant exprs.
|
||||
if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D)) {
|
||||
// FIXME: This is an ugly hack around the fact that enums don't set their
|
||||
// signedness consistently; see PR3173.
|
||||
APSInt SI = ECD->getInitVal();
|
||||
SI.setIsUnsigned(!E->getType()->isSignedIntegerType());
|
||||
// FIXME: This is an ugly hack around the fact that enums don't
|
||||
// set their width (!?!) consistently; see PR3173.
|
||||
SI.extOrTrunc(Info.Ctx.getIntWidth(E->getType()));
|
||||
return Success(SI, E);
|
||||
}
|
||||
if (const EnumConstantDecl *ECD = dyn_cast<EnumConstantDecl>(D))
|
||||
return Success(ECD->getInitVal(), E);
|
||||
|
||||
// In C++, const, non-volatile integers initialized with ICEs are ICEs.
|
||||
// In C, they can also be folded, although they are not ICEs.
|
||||
|
|
|
@ -5694,6 +5694,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
|
|||
// First value, set to zero.
|
||||
EltTy = Context.IntTy;
|
||||
EnumVal.zextOrTrunc(static_cast<uint32_t>(Context.getTypeSize(EltTy)));
|
||||
EnumVal.setIsSigned(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5908,19 +5909,8 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
|
|||
// enumerator value fits in an int, type it as an int, otherwise type it the
|
||||
// same as the enumerator decl itself. This means that in "enum { X = 1U }"
|
||||
// that X has type 'int', not 'unsigned'.
|
||||
if (ECD->getType() == Context.IntTy) {
|
||||
// Make sure the init value is signed.
|
||||
llvm::APSInt IV = ECD->getInitVal();
|
||||
IV.setIsSigned(true);
|
||||
ECD->setInitVal(IV);
|
||||
|
||||
if (getLangOptions().CPlusPlus)
|
||||
// C++ [dcl.enum]p4: Following the closing brace of an
|
||||
// enum-specifier, each enumerator has the type of its
|
||||
// enumeration.
|
||||
ECD->setType(EnumType);
|
||||
continue; // Already int type.
|
||||
}
|
||||
if (!getLangOptions().CPlusPlus && ECD->getType() == Context.IntTy)
|
||||
continue;
|
||||
|
||||
// Determine whether the value fits into an int.
|
||||
llvm::APSInt InitVal = ECD->getInitVal();
|
||||
|
@ -5935,7 +5925,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc,
|
|||
QualType NewTy;
|
||||
unsigned NewWidth;
|
||||
bool NewSign;
|
||||
if (FitsInInt) {
|
||||
if (FitsInInt && !getLangOptions().CPlusPlus) {
|
||||
NewTy = Context.IntTy;
|
||||
NewWidth = IntWidth;
|
||||
NewSign = true;
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
// RUN: clang-cc -emit-llvm-only -verify %s
|
||||
|
||||
enum A { a } __attribute((packed));
|
||||
int func(A x) { return x==a; }
|
Загрузка…
Ссылка в новой задаче