aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-03-14 00:20:21 +0000
committerDouglas Gregor <dgregor@apple.com>2009-03-14 00:20:21 +0000
commitf80a9d5c2ccc465211178223799217f7a42774ae (patch)
treea313c405cc7b46ac61c77754b24aa677b66aecc6 /lib/Sema/SemaTemplate.cpp
parent8af2c16571f3aade6d47ce81fa3857d01d375719 (diff)
Check for overflow and signedness problems with template
arguments. Eliminates a FIXME. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66993 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r--lib/Sema/SemaTemplate.cpp41
1 files changed, 31 insertions, 10 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 142cc453f3..fd1eaf0ace 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1266,16 +1266,42 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
return true;
}
- // FIXME: Check overflow of template arguments?
+ QualType IntegerType = Context.getCanonicalType(ParamType);
+ if (const EnumType *Enum = IntegerType->getAsEnumType())
+ IntegerType = Enum->getDecl()->getIntegerType();
+
+ if (!Arg->isValueDependent()) {
+ // Check that an unsigned parameter does not receive a negative
+ // value.
+ if (IntegerType->isUnsignedIntegerType()
+ && (Value.isSigned() && Value.isNegative())) {
+ Diag(Arg->getSourceRange().getBegin(), diag::err_template_arg_negative)
+ << 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);
+ if (Value.getActiveBits() > AllowedBits) {
+ Diag(Arg->getSourceRange().getBegin(),
+ diag::err_template_arg_too_large)
+ << 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());
+ }
if (Converted) {
// Add the value of this argument to the list of converted
// arguments. We use the bitwidth and signedness of the template
// parameter.
- QualType IntegerType = Context.getCanonicalType(ParamType);
- if (const EnumType *Enum = IntegerType->getAsEnumType())
- IntegerType = Enum->getDecl()->getIntegerType();
-
if (Arg->isValueDependent()) {
// The argument is value-dependent. Create a new
// TemplateArgument with the converted expression.
@@ -1283,11 +1309,6 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
return false;
}
- unsigned ExpectedBits = Context.getTypeSize(IntegerType);
- if (Value.getBitWidth() != ExpectedBits)
- Value.extOrTrunc(ExpectedBits);
- Value.setIsSigned(IntegerType->isSignedIntegerType());
-
Converted->push_back(TemplateArgument(StartLoc, Value,
Context.getCanonicalType(IntegerType)));
}