[cfe-commits] r99611 - /cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
Douglas Gregor
dgregor at apple.com
Thu Mar 25 22:50:28 PDT 2010
Author: dgregor
Date: Fri Mar 26 00:50:28 2010
New Revision: 99611
URL: http://llvm.org/viewvc/llvm-project?rev=99611&view=rev
Log:
When deducing an integral template argument for a non-type template
parameter, keep the integral value exactly as it was in the source
code rather than trying to convert it to the type of the non-type
template parameter (which may still be dependent!). The value will
then be converted to the appropriate type once we check the resulting
template arguments. Fixes PR6707.
Modified:
cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=99611&r1=99610&r2=99611&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Fri Mar 26 00:50:28 2010
@@ -48,6 +48,27 @@
using namespace clang;
+/// \brief Compare two APSInts, extending and switching the sign as
+/// necessary to compare their values regardless of underlying type.
+static bool hasSameExtendedValue(llvm::APSInt X, llvm::APSInt Y) {
+ if (Y.getBitWidth() > X.getBitWidth())
+ X.extend(Y.getBitWidth());
+ else if (Y.getBitWidth() < X.getBitWidth())
+ Y.extend(X.getBitWidth());
+
+ // If there is a signedness mismatch, correct it.
+ if (X.isSigned() != Y.isSigned()) {
+ // If the signed value is negative, then the values cannot be the same.
+ if ((Y.isSigned() && Y.isNegative()) || (X.isSigned() && X.isNegative()))
+ return false;
+
+ Y.setIsSigned(true);
+ X.setIsSigned(true);
+ }
+
+ return X == Y;
+}
+
static Sema::TemplateDeductionResult
DeduceTemplateArguments(Sema &S,
TemplateParameterList *TemplateParams,
@@ -74,47 +95,30 @@
static Sema::TemplateDeductionResult
DeduceNonTypeTemplateArgument(Sema &S,
NonTypeTemplateParmDecl *NTTP,
- llvm::APSInt Value,
+ llvm::APSInt Value, QualType ValueType,
Sema::TemplateDeductionInfo &Info,
llvm::SmallVectorImpl<TemplateArgument> &Deduced) {
assert(NTTP->getDepth() == 0 &&
"Cannot deduce non-type template argument with depth > 0");
if (Deduced[NTTP->getIndex()].isNull()) {
- QualType T = NTTP->getType();
-
- // FIXME: Make sure we didn't overflow our data type!
- unsigned AllowedBits = S.Context.getTypeSize(T);
- if (Value.getBitWidth() != AllowedBits)
- Value.extOrTrunc(AllowedBits);
- Value.setIsSigned(T->isSignedIntegerType());
-
- Deduced[NTTP->getIndex()] = TemplateArgument(Value, T);
+ Deduced[NTTP->getIndex()] = TemplateArgument(Value, ValueType);
return Sema::TDK_Success;
}
- assert(Deduced[NTTP->getIndex()].getKind() == TemplateArgument::Integral);
-
- // If the template argument was previously deduced to a negative value,
- // then our deduction fails.
- const llvm::APSInt *PrevValuePtr = Deduced[NTTP->getIndex()].getAsIntegral();
- if (PrevValuePtr->isNegative()) {
+ if (Deduced[NTTP->getIndex()].getKind() != TemplateArgument::Integral) {
Info.Param = NTTP;
Info.FirstArg = Deduced[NTTP->getIndex()];
- Info.SecondArg = TemplateArgument(Value, NTTP->getType());
- return Sema::TDK_Inconsistent;
+ Info.SecondArg = TemplateArgument(Value, ValueType);
+ return Sema::TDK_Inconsistent;
}
- llvm::APSInt PrevValue = *PrevValuePtr;
- if (Value.getBitWidth() > PrevValue.getBitWidth())
- PrevValue.zext(Value.getBitWidth());
- else if (Value.getBitWidth() < PrevValue.getBitWidth())
- Value.zext(PrevValue.getBitWidth());
-
- if (Value != PrevValue) {
+ // Extent the smaller of the two values.
+ llvm::APSInt PrevValue = *Deduced[NTTP->getIndex()].getAsIntegral();
+ if (!hasSameExtendedValue(PrevValue, Value)) {
Info.Param = NTTP;
Info.FirstArg = Deduced[NTTP->getIndex()];
- Info.SecondArg = TemplateArgument(Value, NTTP->getType());
+ Info.SecondArg = TemplateArgument(Value, ValueType);
return Sema::TDK_Inconsistent;
}
@@ -137,8 +141,7 @@
"Expression template argument must be type- or value-dependent.");
if (Deduced[NTTP->getIndex()].isNull()) {
- // FIXME: Clone the Value?
- Deduced[NTTP->getIndex()] = TemplateArgument(Value);
+ Deduced[NTTP->getIndex()] = TemplateArgument(Value->Retain());
return Sema::TDK_Success;
}
@@ -569,7 +572,8 @@
if (const ConstantArrayType *ConstantArrayArg
= dyn_cast<ConstantArrayType>(ArrayArg)) {
llvm::APSInt Size(ConstantArrayArg->getSize());
- return DeduceNonTypeTemplateArgument(S, NTTP, Size,
+ return DeduceNonTypeTemplateArgument(S, NTTP, Size,
+ S.Context.getSizeType(),
Info, Deduced);
}
if (const DependentSizedArrayType *DependentArrayArg
@@ -816,8 +820,7 @@
case TemplateArgument::Integral:
if (Arg.getKind() == TemplateArgument::Integral) {
- // FIXME: Zero extension + sign checking here?
- if (*Param.getAsIntegral() == *Arg.getAsIntegral())
+ if (hasSameExtendedValue(*Param.getAsIntegral(), *Arg.getAsIntegral()))
return Sema::TDK_Success;
Info.FirstArg = Param;
@@ -840,9 +843,9 @@
if (NonTypeTemplateParmDecl *NTTP
= getDeducedParameterFromExpr(Param.getAsExpr())) {
if (Arg.getKind() == TemplateArgument::Integral)
- // FIXME: Sign problems here
return DeduceNonTypeTemplateArgument(S, NTTP,
*Arg.getAsIntegral(),
+ Arg.getIntegralType(),
Info, Deduced);
if (Arg.getKind() == TemplateArgument::Expression)
return DeduceNonTypeTemplateArgument(S, NTTP, Arg.getAsExpr(),
More information about the cfe-commits
mailing list