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 | 52aba87df72b8c2ca4796b559a9544370ccfd8e2 (patch) | |
tree | 13ef110cc4a2ea454e0ceb275a694ad33cb30f15 /clang/lib/Sema/SemaTemplate.cpp | |
parent | 9a46804ca8ca73d0af13b1391b91ff91780008c2 (diff) | |
download | bcm5719-llvm-52aba87df72b8c2ca4796b559a9544370ccfd8e2.tar.gz bcm5719-llvm-52aba87df72b8c2ca4796b559a9544370ccfd8e2.zip |
Check for overflow and signedness problems with template
arguments. Eliminates a FIXME.
llvm-svn: 66993
Diffstat (limited to 'clang/lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 142cc453f36..fd1eaf0ace6 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/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))); } |