Fix the overflow calculation in Sema::CheckTemplateArgument to be a bit more

accurate.

llvm-svn: 92018
This commit is contained in:
Eli Friedman 2009-12-23 18:44:58 +00:00
parent 66ffa50e6d
commit 38b9ad88e2
2 changed files with 19 additions and 2 deletions

View File

@ -2488,7 +2488,14 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
// Check that we don't overflow the template parameter type.
unsigned AllowedBits = Context.getTypeSize(IntegerType);
if (Value.getActiveBits() > AllowedBits) {
unsigned RequiredBits;
if (IntegerType->isUnsignedIntegerType())
RequiredBits = Value.getActiveBits();
else if (Value.isUnsigned())
RequiredBits = Value.getActiveBits() + 1;
else
RequiredBits = Value.getMinSignedBits();
if (RequiredBits > AllowedBits) {
Diag(Arg->getSourceRange().getBegin(),
diag::err_template_arg_too_large)
<< Value.toString(10) << Param->getType()

View File

@ -105,13 +105,23 @@ A7c<(&Z::int_member)> *a18_3; // expected-error{{non-type template argument cann
template<unsigned char C> struct Overflow; // expected-note{{template parameter is declared here}}
Overflow<5> *overflow1; // okay
Overflow<256> *overflow2; // expected-error{{non-type template argument value '256' is too large for template parameter of type 'unsigned char'}}
Overflow<255> *overflow2; // okay
Overflow<256> *overflow3; // expected-error{{non-type template argument value '256' is too large for template parameter of type 'unsigned char'}}
template<unsigned> struct Signedness; // expected-note{{template parameter is declared here}}
Signedness<10> *signedness1; // okay
Signedness<-10> *signedness2; // expected-error{{non-type template argument provides negative value '-10' for unsigned template parameter of type 'unsigned int'}}
template<signed char C> struct SignedOverflow; // expected-note 3 {{template parameter is declared here}}
SignedOverflow<1> *signedoverflow1;
SignedOverflow<-1> *signedoverflow2;
SignedOverflow<-128> *signedoverflow3;
SignedOverflow<-129> *signedoverflow4; // expected-error{{non-type template argument value '-129' is too large for template parameter of type 'signed char'}}
SignedOverflow<127> *signedoverflow5;
SignedOverflow<128> *signedoverflow6; // expected-error{{non-type template argument value '128' is too large for template parameter of type 'signed char'}}
SignedOverflow<(unsigned char)128> *signedoverflow7; // expected-error{{non-type template argument value '128' is too large for template parameter of type 'signed char'}}
// Check canonicalization of template arguments.
template<int (*)(int, int)> struct FuncPtr0;
int func0(int, int);