diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-05-04 21:55:00 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-05-04 21:55:00 +0000 |
commit | c7469374548b06e50aa8b4d41bf1a35338e9b358 (patch) | |
tree | b759ac27e202c12d6f10398651337a5599616f70 /lib/Sema/SemaTemplate.cpp | |
parent | 1f382510495b581e3028d670a23c7dcf5440be62 (diff) |
When converting an integral template argument value to a non-type
template parameter of type 'bool', force the value to be zero or
one. Fixes <rdar://problem/9169404>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130873 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index ef0912485b..7a4e54de0f 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -3501,29 +3501,46 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, return ExprError(); } + // Add the value of this argument to the list of converted + // arguments. We use the bitwidth and signedness of the template + // parameter. + if (Arg->isValueDependent()) { + // The argument is value-dependent. Create a new + // TemplateArgument with the converted expression. + Converted = TemplateArgument(Arg); + return Owned(Arg); + } + QualType IntegerType = Context.getCanonicalType(ParamType); if (const EnumType *Enum = IntegerType->getAs<EnumType>()) IntegerType = Context.getCanonicalType(Enum->getDecl()->getIntegerType()); - if (!Arg->isValueDependent()) { + if (ParamType->isBooleanType()) { + // Value must be zero or one. + Value = Value != 0; + unsigned AllowedBits = Context.getTypeSize(IntegerType); + if (Value.getBitWidth() != AllowedBits) + Value = Value.extOrTrunc(AllowedBits); + Value.setIsSigned(IntegerType->isSignedIntegerType()); + } else { 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); if (Value.getBitWidth() != AllowedBits) Value = Value.extOrTrunc(AllowedBits); Value.setIsSigned(IntegerType->isSignedIntegerType()); - + // Complain if an unsigned parameter received a negative value. if (IntegerType->isUnsignedIntegerType() - && (OldValue.isSigned() && OldValue.isNegative())) { + && (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); } - + // Complain if we overflowed the template parameter's type. unsigned RequiredBits; if (IntegerType->isUnsignedIntegerType()) @@ -3541,16 +3558,6 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, } } - // Add the value of this argument to the list of converted - // arguments. We use the bitwidth and signedness of the template - // parameter. - if (Arg->isValueDependent()) { - // The argument is value-dependent. Create a new - // TemplateArgument with the converted expression. - Converted = TemplateArgument(Arg); - return Owned(Arg); - } - Converted = TemplateArgument(Value, ParamType->isEnumeralType() ? ParamType : IntegerType); |