DmitryPolukhin created this revision.
DmitryPolukhin added a reviewer: rnk.
DmitryPolukhin added a subscriber: cfe-commits.

MSVC doesn't report even warning for cast from private base class to derived.

http://reviews.llvm.org/D19477

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaCast.cpp
  test/SemaCXX/ext_ms_downcast.cpp

Index: test/SemaCXX/ext_ms_downcast.cpp
===================================================================
--- /dev/null
+++ test/SemaCXX/ext_ms_downcast.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -fms-compatibility -verify %s
+// RUN: %clang_cc1 -fsyntax-only -DNO_MS_COMPATIBILITY -verify %s
+
+// Minimal reproducer.
+class A {};
+class B : A {}; // expected-note 2 {{implicitly declared private here}}
+
+B* foo(A* p) {
+  return static_cast<B*>(p);
+#ifdef NO_MS_COMPATIBILITY
+  // expected-error@-2 {{cannot cast private base class 'A' to 'B'}}
+#else
+  // expected-warning@-4 {{cast private base class 'A' to 'B' is a Microsoft 
extension}}
+#endif
+}
+
+A* bar(B* p) {
+  return static_cast<A*>(p); // expected-error {{cannot cast 'B' to its 
private base class 'A'}}
+}
+
+// from atlframe.h
+template <class T>
+class CUpdateUI {
+public:
+  CUpdateUI() {
+    T* pT = static_cast<T*>(this);
+#ifdef NO_MS_COMPATIBILITY
+    // expected-error@-2 {{cannot cast private base class}}
+#else
+    // expected-warning@-4 {{cast private base class 'CUpdateUI<CMDIFrame>' to 
'CMDIFrame' is a Microsoft extension}}
+#endif
+  }
+};
+
+// from sample WTL/MDIDocVw (mainfrm.h
+class CMDIFrame : CUpdateUI<CMDIFrame> {};
+// expected-note@-1 {{implicitly declared private here}}
+// expected-note@-2 {{in instantiation of member function}}
+
+CMDIFrame wndMain;
Index: lib/Sema/SemaCast.cpp
===================================================================
--- lib/Sema/SemaCast.cpp
+++ lib/Sema/SemaCast.cpp
@@ -1344,10 +1344,11 @@
   }
 
   if (!CStyle) {
-    switch (Self.CheckBaseClassAccess(OpRange.getBegin(),
-                                      SrcType, DestType,
-                                      Paths.front(),
-                                diag::err_downcast_from_inaccessible_base)) {
+    unsigned Diag = Self.getLangOpts().MSVCCompat
+                        ? diag::ext_ms_downcast_from_inaccessible_base
+                        : diag::err_downcast_from_inaccessible_base;
+    switch (Self.CheckBaseClassAccess(OpRange.getBegin(), SrcType, DestType,
+                                      Paths.front(), Diag)) {
     case Sema::AR_accessible:
     case Sema::AR_delayed:     // be optimistic
     case Sema::AR_dependent:   // be optimistic
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -5764,6 +5764,9 @@
   "cannot cast %0 to %1 via virtual base %2">;
 def err_downcast_from_inaccessible_base : Error<
   "cannot cast %select{private|protected}2 base class %1 to %0">;
+def ext_ms_downcast_from_inaccessible_base : ExtWarn<
+  "cast %select{private|protected}2 base class %1 to %0 is a Microsoft 
extension">,
+  InGroup<MicrosoftCast>;
 def err_upcast_to_inaccessible_base : Error<
   "cannot cast %0 to its %select{private|protected}2 base class %1">;
 def err_bad_dynamic_cast_not_ref_or_ptr : Error<


Index: test/SemaCXX/ext_ms_downcast.cpp
===================================================================
--- /dev/null
+++ test/SemaCXX/ext_ms_downcast.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -fms-compatibility -verify %s
+// RUN: %clang_cc1 -fsyntax-only -DNO_MS_COMPATIBILITY -verify %s
+
+// Minimal reproducer.
+class A {};
+class B : A {}; // expected-note 2 {{implicitly declared private here}}
+
+B* foo(A* p) {
+  return static_cast<B*>(p);
+#ifdef NO_MS_COMPATIBILITY
+  // expected-error@-2 {{cannot cast private base class 'A' to 'B'}}
+#else
+  // expected-warning@-4 {{cast private base class 'A' to 'B' is a Microsoft extension}}
+#endif
+}
+
+A* bar(B* p) {
+  return static_cast<A*>(p); // expected-error {{cannot cast 'B' to its private base class 'A'}}
+}
+
+// from atlframe.h
+template <class T>
+class CUpdateUI {
+public:
+  CUpdateUI() {
+    T* pT = static_cast<T*>(this);
+#ifdef NO_MS_COMPATIBILITY
+    // expected-error@-2 {{cannot cast private base class}}
+#else
+    // expected-warning@-4 {{cast private base class 'CUpdateUI<CMDIFrame>' to 'CMDIFrame' is a Microsoft extension}}
+#endif
+  }
+};
+
+// from sample WTL/MDIDocVw (mainfrm.h
+class CMDIFrame : CUpdateUI<CMDIFrame> {};
+// expected-note@-1 {{implicitly declared private here}}
+// expected-note@-2 {{in instantiation of member function}}
+
+CMDIFrame wndMain;
Index: lib/Sema/SemaCast.cpp
===================================================================
--- lib/Sema/SemaCast.cpp
+++ lib/Sema/SemaCast.cpp
@@ -1344,10 +1344,11 @@
   }
 
   if (!CStyle) {
-    switch (Self.CheckBaseClassAccess(OpRange.getBegin(),
-                                      SrcType, DestType,
-                                      Paths.front(),
-                                diag::err_downcast_from_inaccessible_base)) {
+    unsigned Diag = Self.getLangOpts().MSVCCompat
+                        ? diag::ext_ms_downcast_from_inaccessible_base
+                        : diag::err_downcast_from_inaccessible_base;
+    switch (Self.CheckBaseClassAccess(OpRange.getBegin(), SrcType, DestType,
+                                      Paths.front(), Diag)) {
     case Sema::AR_accessible:
     case Sema::AR_delayed:     // be optimistic
     case Sema::AR_dependent:   // be optimistic
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -5764,6 +5764,9 @@
   "cannot cast %0 to %1 via virtual base %2">;
 def err_downcast_from_inaccessible_base : Error<
   "cannot cast %select{private|protected}2 base class %1 to %0">;
+def ext_ms_downcast_from_inaccessible_base : ExtWarn<
+  "cast %select{private|protected}2 base class %1 to %0 is a Microsoft extension">,
+  InGroup<MicrosoftCast>;
 def err_upcast_to_inaccessible_base : Error<
   "cannot cast %0 to its %select{private|protected}2 base class %1">;
 def err_bad_dynamic_cast_not_ref_or_ptr : Error<
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to