Make sure that EnumConstantDecls always get a type, even when they have type-dependent initializers.

llvm-svn: 86197
This commit is contained in:
Douglas Gregor 2009-11-06 00:03:12 +00:00
parent 006f9353e1
commit b2186fe23c
2 changed files with 36 additions and 14 deletions

View File

@ -5362,21 +5362,25 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
llvm::APSInt EnumVal(32);
QualType EltTy;
if (Val && !Val->isTypeDependent()) {
// Make sure to promote the operand type to int.
UsualUnaryConversions(Val);
if (Val != val.get()) {
val.release();
val = Val;
}
if (Val) {
if (Val->isTypeDependent())
EltTy = Context.DependentTy;
else {
// Make sure to promote the operand type to int.
UsualUnaryConversions(Val);
if (Val != val.get()) {
val.release();
val = Val;
}
// C99 6.7.2.2p2: Make sure we have an integer constant expression.
SourceLocation ExpLoc;
if (!Val->isValueDependent() &&
VerifyIntegerConstantExpression(Val, &EnumVal)) {
Val = 0;
} else {
EltTy = Val->getType();
// C99 6.7.2.2p2: Make sure we have an integer constant expression.
SourceLocation ExpLoc;
if (!Val->isValueDependent() &&
VerifyIntegerConstantExpression(Val, &EnumVal)) {
Val = 0;
} else {
EltTy = Val->getType();
}
}
}
@ -5398,6 +5402,8 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,
}
}
assert(!EltTy.isNull() && "Enum constant with NULL type");
val.release();
return EnumConstantDecl::Create(Context, Enum, IdLoc, Id, EltTy,
Val, EnumVal);

View File

@ -5,3 +5,19 @@ template <Enum v> struct C {
typedef C<v> Self;
};
template struct C<val>;
template<typename T>
struct get_size {
static const unsigned value = sizeof(T);
};
template<typename T>
struct X0 {
enum {
Val1 = get_size<T>::value,
Val2,
SumOfValues = Val1 + Val2
};
};
X0<int> x0i;