[cfe-commits] r130873 - in /cfe/trunk: lib/Sema/SemaTemplate.cpp test/SemaTemplate/partial-spec-instantiate.cpp
Douglas Gregor
dgregor at apple.com
Wed May 4 14:55:00 PDT 2011
Author: dgregor
Date: Wed May 4 16:55:00 2011
New Revision: 130873
URL: http://llvm.org/viewvc/llvm-project?rev=130873&view=rev
Log:
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>.
Modified:
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/test/SemaTemplate/partial-spec-instantiate.cpp
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=130873&r1=130872&r2=130873&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed May 4 16:55:00 2011
@@ -3501,29 +3501,46 @@
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 @@
}
}
- // 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);
Modified: cfe/trunk/test/SemaTemplate/partial-spec-instantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/partial-spec-instantiate.cpp?rev=130873&r1=130872&r2=130873&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/partial-spec-instantiate.cpp (original)
+++ cfe/trunk/test/SemaTemplate/partial-spec-instantiate.cpp Wed May 4 16:55:00 2011
@@ -38,3 +38,13 @@
return y.m + y2.m;
}
}
+
+// <rdar://problem/9169404>
+namespace rdar9169404 {
+ template<typename T, T N> struct X { };
+ template<bool C> struct X<bool, C> {
+ typedef int type;
+ };
+
+ X<bool, -1>::type value;
+}
More information about the cfe-commits
mailing list