diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-03-14 00:20:21 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-03-14 00:20:21 +0000 |
commit | f80a9d5c2ccc465211178223799217f7a42774ae (patch) | |
tree | a313c405cc7b46ac61c77754b24aa677b66aecc6 /lib/Sema/SemaTemplate.cpp | |
parent | 8af2c16571f3aade6d47ce81fa3857d01d375719 (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.cpp | 41 |
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))); } |