From: David Majnemer Date: Tue, 2 Jun 2015 22:15:12 +0000 (+0000) Subject: [MSVC Compatibility] Permit static_cast from void-ptr to function-ptr X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=435af83feb246ca6cd3f4a8db47710fc412ca32f;p=clang [MSVC Compatibility] Permit static_cast from void-ptr to function-ptr The MSVC 2013 and 2015 implementation of std::atomic is specialized for pointer types. The member functions are implemented using a static_cast from void-ptr to function-ptr which is not allowed in the standard. Permit this conversion if -fms-compatibility is present. This fixes PR23733. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@238877 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 9ccd5adf21..d79aeb2e8f 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -5390,6 +5390,10 @@ def err_bad_const_cast_dest : Error< "which is not a reference, pointer-to-object, or pointer-to-data-member">; def ext_cast_fn_obj : Extension< "cast between pointer-to-function and pointer-to-object is an extension">; +def ext_ms_cast_fn_obj : ExtWarn< + "static_cast between pointer-to-function and pointer-to-object is a " + "Microsoft extension">, + InGroup; def warn_cxx98_compat_cast_fn_obj : Warning< "cast between pointer-to-function and pointer-to-object is incompatible with C++98">, InGroup, DefaultIgnore; diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp index 091e77936c..8683d03007 100644 --- a/lib/Sema/SemaCast.cpp +++ b/lib/Sema/SemaCast.cpp @@ -1081,6 +1081,14 @@ static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, Kind = CK_BitCast; return TC_Success; } + + // Microsoft permits static_cast from 'pointer-to-void' to + // 'pointer-to-function'. + if (Self.getLangOpts().MSVCCompat && DestPointee->isFunctionType()) { + Self.Diag(OpRange.getBegin(), diag::ext_ms_cast_fn_obj) << OpRange; + Kind = CK_BitCast; + return TC_Success; + } } else if (DestType->isObjCObjectPointerType()) { // allow both c-style cast and static_cast of objective-c pointers as diff --git a/test/SemaCXX/MicrosoftCompatibility-cxx98.cpp b/test/SemaCXX/MicrosoftCompatibility-cxx98.cpp index 0c7d354c30..e72878e302 100644 --- a/test/SemaCXX/MicrosoftCompatibility-cxx98.cpp +++ b/test/SemaCXX/MicrosoftCompatibility-cxx98.cpp @@ -6,3 +6,5 @@ enum ENUM; // expected-warning {{forward references to 'enum' types are a Micros ENUM *var = 0; ENUM var2 = (ENUM)3; enum ENUM1* var3 = 0;// expected-warning {{forward references to 'enum' types are a Microsoft extension}} + +void (*PR23733)() = static_cast((void *)0); // expected-warning {{static_cast between pointer-to-function and pointer-to-object is a Microsoft extension}}