]> granicus.if.org Git - clang/commitdiff
When doing overload resolution, expressions that are value dependent but not type...
authorAnders Carlsson <andersca@mac.com>
Fri, 28 Aug 2009 15:55:56 +0000 (15:55 +0000)
committerAnders Carlsson <andersca@mac.com>
Fri, 28 Aug 2009 15:55:56 +0000 (15:55 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80369 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaOverload.cpp
test/SemaCXX/overload-value-dep-arg.cpp [new file with mode: 0644]

index dffaf41feb1162f942d580d86921e73311c491b9..ab1062f370bcf19b084bb4f99ae710b980e58be4 100644 (file)
@@ -870,6 +870,18 @@ BuildSimilarlyQualifiedPointerType(const PointerType *FromPtr,
   return Context.getPointerType(CanonToPointee.getQualifiedType(Quals));
 }
 
+static bool isNullPointerConstantForConversion(Expr *Expr, 
+                                               bool InOverloadResolution,
+                                               ASTContext &Context) {
+  // Handle value-dependent integral null pointer constants correctly.
+  // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#903
+  if (Expr->isValueDependent() && !Expr->isTypeDependent() &&
+      Expr->getType()->isIntegralType())
+    return !InOverloadResolution;
+
+  return Expr->isNullPointerConstant(Context);
+}
+  
 /// IsPointerConversion - Determines whether the conversion of the
 /// expression From, which has the (possibly adjusted) type FromType,
 /// can be converted to the type ToType via a pointer conversion (C++
@@ -897,7 +909,7 @@ bool Sema::IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
 
   // Conversion from a null pointer constant to any Objective-C pointer type. 
   if (ToType->isObjCObjectPointerType() && 
-      From->isNullPointerConstant(Context)) {
+      isNullPointerConstantForConversion(From, InOverloadResolution, Context)) {
     ConvertedType = ToType;
     return true;
   }
@@ -910,14 +922,16 @@ bool Sema::IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
   }
   // Blocks: A null pointer constant can be converted to a block
   // pointer type.
-  if (ToType->isBlockPointerType() && From->isNullPointerConstant(Context)) {
+  if (ToType->isBlockPointerType() && 
+      isNullPointerConstantForConversion(From, InOverloadResolution, Context)) {
     ConvertedType = ToType;
     return true;
   }
 
   // If the left-hand-side is nullptr_t, the right side can be a null
   // pointer constant.
-  if (ToType->isNullPtrType() && From->isNullPointerConstant(Context)) {
+  if (ToType->isNullPtrType() && 
+      isNullPointerConstantForConversion(From, InOverloadResolution, Context)) {
     ConvertedType = ToType;
     return true;
   }
@@ -927,7 +941,7 @@ bool Sema::IsPointerConversion(Expr *From, QualType FromType, QualType ToType,
     return false;
 
   // A null pointer constant can be converted to a pointer type (C++ 4.10p1).
-  if (From->isNullPointerConstant(Context)) {
+  if (isNullPointerConstantForConversion(From, InOverloadResolution, Context)) {
     ConvertedType = ToType;
     return true;
   }
diff --git a/test/SemaCXX/overload-value-dep-arg.cpp b/test/SemaCXX/overload-value-dep-arg.cpp
new file mode 100644 (file)
index 0000000..1e94d5a
--- /dev/null
@@ -0,0 +1,13 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+class C {
+  C(void*);
+};
+
+int f(const C&);
+int f(unsigned long);
+
+template<typename T> int f(const T* t) {
+  return f(reinterpret_cast<unsigned long>(t));
+}
+