aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-03-25 22:21:04 +0000
committerDouglas Gregor <dgregor@apple.com>2010-03-25 22:21:04 +0000
commit684d096c204c5eef29c10777bce890400d235d8c (patch)
treea7e3f7f7e3f10eecec39df906746c0aa8368e140 /lib/Sema/SemaTemplate.cpp
parenteab5d1eaaa662c849f1f9920dc8c6a31d7c32d47 (diff)
Warn when the conversion of an integral non-type template argument to
the type of its corresponding non-type template parameter changes the value. Previously, we were diagnosing this as an error, which was wrong. We give reasonably nice warnings like: test/SemaTemplate/temp_arg_nontype.cpp:100:10: warning: non-type template argument value '256' truncated to '0' for template parameter of type 'unsigned char' Overflow<256> *overflow3; // expected-warning{{non-type template ... ^~~ test/SemaTemplate/temp_arg_nontype.cpp:96:24: note: template parameter is declared here template<unsigned char C> struct Overflow; ^ git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99561 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r--lib/Sema/SemaTemplate.cpp39
1 files changed, 20 insertions, 19 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 5a1bec927c..0102aefa7e 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -2554,38 +2554,39 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
IntegerType = Context.getCanonicalType(Enum->getDecl()->getIntegerType());
if (!Arg->isValueDependent()) {
- // Check that an unsigned parameter does not receive a negative
- // value.
+ llvm::APSInt OldValue = Value;
+
+ // Coerce the template argument's value to the value it will have
+ // based on the template parameter's type.
+ unsigned AllowedBits = Context.getTypeSize(IntegerType);
+ Value.setIsSigned(IntegerType->isSignedIntegerType());
+ if (Value.getBitWidth() != AllowedBits)
+ Value.extOrTrunc(AllowedBits);
+
+ // Complain if an unsigned parameter received a negative value.
if (IntegerType->isUnsignedIntegerType()
- && (Value.isSigned() && Value.isNegative())) {
- Diag(Arg->getSourceRange().getBegin(), diag::err_template_arg_negative)
- << Value.toString(10) << Param->getType()
+ && (OldValue.isSigned() && OldValue.isNegative())) {
+ Diag(Arg->getSourceRange().getBegin(), diag::warn_template_arg_negative)
+ << OldValue.toString(10) << Value.toString(10) << Param->getType()
<< Arg->getSourceRange();
Diag(Param->getLocation(), diag::note_template_param_here);
- return true;
}
- // Check that we don't overflow the template parameter type.
- unsigned AllowedBits = Context.getTypeSize(IntegerType);
+ // Complain if we overflowed the template parameter's type.
unsigned RequiredBits;
if (IntegerType->isUnsignedIntegerType())
- RequiredBits = Value.getActiveBits();
- else if (Value.isUnsigned())
- RequiredBits = Value.getActiveBits() + 1;
+ RequiredBits = OldValue.getActiveBits();
+ else if (OldValue.isUnsigned())
+ RequiredBits = OldValue.getActiveBits() + 1;
else
- RequiredBits = Value.getMinSignedBits();
+ RequiredBits = OldValue.getMinSignedBits();
if (RequiredBits > AllowedBits) {
Diag(Arg->getSourceRange().getBegin(),
- diag::err_template_arg_too_large)
- << Value.toString(10) << Param->getType()
+ diag::warn_template_arg_too_large)
+ << OldValue.toString(10) << Value.toString(10) << Param->getType()
<< Arg->getSourceRange();
Diag(Param->getLocation(), diag::note_template_param_here);
- return true;
}
-
- if (Value.getBitWidth() != AllowedBits)
- Value.extOrTrunc(AllowedBits);
- Value.setIsSigned(IntegerType->isSignedIntegerType());
}
// Add the value of this argument to the list of converted