forked from OSchip/llvm-project
Fix a few cases where enum constant handling was using
ASTContext::getTypeSize() rather than ASTContext::getIntWidth() for the width of an integral type. The former includes padding for bools (to the target's size) while the latter does not, so we woud end up zero-extending bools to the target width when we shouldn't. Fixes a crash-on-valid in the included test. llvm-svn: 101372
This commit is contained in:
parent
ff3c8b7eaf
commit
c1cf814c8b
|
|
@ -6006,7 +6006,7 @@ static bool isRepresentableIntegerValue(ASTContext &Context,
|
||||||
llvm::APSInt &Value,
|
llvm::APSInt &Value,
|
||||||
QualType T) {
|
QualType T) {
|
||||||
assert(T->isIntegralType() && "Integral type required!");
|
assert(T->isIntegralType() && "Integral type required!");
|
||||||
unsigned BitWidth = Context.getTypeSize(T);
|
unsigned BitWidth = Context.getIntWidth(T);
|
||||||
|
|
||||||
if (Value.isUnsigned() || Value.isNonNegative())
|
if (Value.isUnsigned() || Value.isNonNegative())
|
||||||
return Value.getActiveBits() < BitWidth;
|
return Value.getActiveBits() < BitWidth;
|
||||||
|
|
@ -6139,7 +6139,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
|
||||||
// value, then increment.
|
// value, then increment.
|
||||||
EnumVal = LastEnumConst->getInitVal();
|
EnumVal = LastEnumConst->getInitVal();
|
||||||
EnumVal.setIsSigned(EltTy->isSignedIntegerType());
|
EnumVal.setIsSigned(EltTy->isSignedIntegerType());
|
||||||
EnumVal.zextOrTrunc(Context.getTypeSize(EltTy));
|
EnumVal.zextOrTrunc(Context.getIntWidth(EltTy));
|
||||||
++EnumVal;
|
++EnumVal;
|
||||||
|
|
||||||
// If we're not in C++, diagnose the overflow of enumerator values,
|
// If we're not in C++, diagnose the overflow of enumerator values,
|
||||||
|
|
@ -6161,7 +6161,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
|
||||||
if (!EltTy->isDependentType()) {
|
if (!EltTy->isDependentType()) {
|
||||||
// Make the enumerator value match the signedness and size of the
|
// Make the enumerator value match the signedness and size of the
|
||||||
// enumerator's type.
|
// enumerator's type.
|
||||||
EnumVal.zextOrTrunc(Context.getTypeSize(EltTy));
|
EnumVal.zextOrTrunc(Context.getIntWidth(EltTy));
|
||||||
EnumVal.setIsSigned(EltTy->isSignedIntegerType());
|
EnumVal.setIsSigned(EltTy->isSignedIntegerType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
|
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
|
||||||
|
|
||||||
// C++ [expr.const]p1:
|
// C++ [expr.const]p1:
|
||||||
// In several places, C++ requires expressions that evaluate to an integral
|
// In several places, C++ requires expressions that evaluate to an integral
|
||||||
// or enumeration constant: as array bounds, as case expressions, as
|
// or enumeration constant: as array bounds, as case expressions, as
|
||||||
|
|
@ -79,5 +78,10 @@ template <int itval, Enum etval> struct C {
|
||||||
};
|
};
|
||||||
|
|
||||||
template struct C<1, eval>;
|
template struct C<1, eval>;
|
||||||
//template struct C<cval, ceval>;
|
template struct C<cval, ceval>;
|
||||||
//template struct C<Struct::sval, Struct::seval>;
|
template struct C<Struct::sval, Struct::seval>;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
a = sizeof(int) == 8,
|
||||||
|
b = a? 8 : 4
|
||||||
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue