[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