From 85bd1206796df79a61387d0cc8f75a289850a6c0 Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Tue, 2 Jun 2015 22:15:12 +0000 Subject: [PATCH] [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. llvm-svn: 238877 --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 4 ++++ clang/lib/Sema/SemaCast.cpp | 8 ++++++++ clang/test/SemaCXX/MicrosoftCompatibility-cxx98.cpp | 2 ++ 3 files changed, 14 insertions(+) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 9ccd5ad..d79aeb2 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/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/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 091e779..8683d03 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/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/clang/test/SemaCXX/MicrosoftCompatibility-cxx98.cpp b/clang/test/SemaCXX/MicrosoftCompatibility-cxx98.cpp index 0c7d354..e72878e 100644 --- a/clang/test/SemaCXX/MicrosoftCompatibility-cxx98.cpp +++ b/clang/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}} -- 2.7.4