]> granicus.if.org Git - clang/commitdiff
[MSVC Compatibility] Permit static_cast from void-ptr to function-ptr
authorDavid Majnemer <david.majnemer@gmail.com>
Tue, 2 Jun 2015 22:15:12 +0000 (22:15 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Tue, 2 Jun 2015 22:15:12 +0000 (22:15 +0000)
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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaCast.cpp
test/SemaCXX/MicrosoftCompatibility-cxx98.cpp

index 9ccd5adf21abb94587789209ada99aa7dbd2e9e8..d79aeb2e8f163914c39e80a9991f8488ec7c0202 100644 (file)
@@ -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<Microsoft>;
 def warn_cxx98_compat_cast_fn_obj : Warning<
   "cast between pointer-to-function and pointer-to-object is incompatible with C++98">,
   InGroup<CXX98CompatPedantic>, DefaultIgnore;
index 091e77936c1e22eff0387a37aaeba612223db0f8..8683d03007dd8e622e07e2eff3fe0cdd68b310d8 100644 (file)
@@ -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 
index 0c7d354c3065483e6205d33cb20eb2e0c6dd8333..e72878e3024019bc1bf8450ef1ede431f21e15cd 100644 (file)
@@ -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 (*)()>((void *)0); // expected-warning {{static_cast between pointer-to-function and pointer-to-object is a Microsoft extension}}