From: Anders Carlsson Date: Fri, 28 Aug 2009 15:55:56 +0000 (+0000) Subject: When doing overload resolution, expressions that are value dependent but not type... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bbf306bd1d3e674edf40c692a5693a475e961a57;p=clang When doing overload resolution, expressions that are value dependent but not type dependent and of integral type should not be treated as null pointer constants. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80369 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index dffaf41feb..ab1062f370 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -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 index 0000000000..1e94d5a301 --- /dev/null +++ b/test/SemaCXX/overload-value-dep-arg.cpp @@ -0,0 +1,13 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +class C { + C(void*); +}; + +int f(const C&); +int f(unsigned long); + +template int f(const T* t) { + return f(reinterpret_cast(t)); +} +