]> granicus.if.org Git - clang/commitdiff
Fix the overflow calculation in Sema::CheckTemplateArgument to be a bit more
authorEli Friedman <eli.friedman@gmail.com>
Wed, 23 Dec 2009 18:44:58 +0000 (18:44 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Wed, 23 Dec 2009 18:44:58 +0000 (18:44 +0000)
accurate.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92018 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaTemplate.cpp
test/SemaTemplate/temp_arg_nontype.cpp

index e6bd77d208a8b316bd7577bdac4a5d2d9fd38afd..3dd024309193abaa31f01f5c3c3610efe4c0bf43 100644 (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()
index 98e0b5dc5ddf80e33e36def9473b3c12cf516a5f..133b8db9491a0b467d6bba6196e65b0d29305690 100644 (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);