[Sema][MSVC] warn at dynamic_cast when /GR- is given
authorZequan Wu <zequanwu@google.com>
Fri, 21 Aug 2020 20:42:20 +0000 (13:42 -0700)
committerZequan Wu <zequanwu@google.com>
Mon, 7 Sep 2020 23:46:58 +0000 (16:46 -0700)
Differential Revision: https://reviews.llvm.org/D86369

clang/include/clang/Basic/DiagnosticGroups.td
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaCast.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/test/SemaCXX/ms_no_dynamic_cast.cpp [new file with mode: 0644]
clang/test/SemaCXX/no_dynamic_cast.cpp [new file with mode: 0644]

index 6b4dcc8..a9bd52b 100644 (file)
@@ -1235,3 +1235,5 @@ in addition with the pragmas or -fmax-tokens flag to get any warnings.
 }
 
 def WebAssemblyExceptionSpec : DiagGroup<"wasm-exception-spec">;
+
+def RTTI : DiagGroup<"rtti">;
index d856f78..e1601da 100644 (file)
@@ -7438,6 +7438,12 @@ def err_no_typeid_with_fno_rtti : Error<
   "use of typeid requires -frtti">;
 def err_no_dynamic_cast_with_fno_rtti : Error<
   "use of dynamic_cast requires -frtti">;
+def warn_no_dynamic_cast_with_rtti_disabled: Warning<
+  "dynamic_cast will not work since RTTI data is disabled by " 
+  "%select{-fno-rtti-data|/GR-}0">, InGroup<RTTI>;
+def warn_no_typeid_with_rtti_disabled: Warning<
+  "typeid will not work since RTTI data is disabled by "
+  "%select{-fno-rtti-data|/GR-}0">, InGroup<RTTI>;
 
 def err_cannot_form_pointer_to_member_of_reference_type : Error<
   "cannot form a pointer-to-member to member %0 of reference type %1">;
index 726900c..b213fb7 100644 (file)
@@ -890,6 +890,18 @@ void CastOperation::CheckDynamicCast() {
     return;
   }
 
+  // Warns when dynamic_cast is used with RTTI data disabled.
+  if (!Self.getLangOpts().RTTIData) {
+    bool MicrosoftABI =
+        Self.getASTContext().getTargetInfo().getCXXABI().isMicrosoft();
+    bool isClangCL = Self.getDiagnostics().getDiagnosticOptions().getFormat() ==
+                     DiagnosticOptions::MSVC;
+    if (MicrosoftABI || !DestPointee->isVoidType())
+      Self.Diag(OpRange.getBegin(),
+                diag::warn_no_dynamic_cast_with_rtti_disabled)
+          << isClangCL;
+  }
+
   // Done. Everything else is run-time checks.
   Kind = CK_Dynamic;
 }
index d1fcdf3..8f8847e 100644 (file)
@@ -646,6 +646,12 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
     return ExprError(Diag(OpLoc, diag::err_no_typeid_with_fno_rtti));
   }
 
+  // Warns when typeid is used with RTTI data disabled.
+  if (!getLangOpts().RTTIData)
+    Diag(OpLoc, diag::warn_no_typeid_with_rtti_disabled)
+        << (getDiagnostics().getDiagnosticOptions().getFormat() ==
+            DiagnosticOptions::MSVC);
+
   QualType TypeInfoType = Context.getTypeDeclType(CXXTypeInfoDecl);
 
   if (isType) {
diff --git a/clang/test/SemaCXX/ms_no_dynamic_cast.cpp b/clang/test/SemaCXX/ms_no_dynamic_cast.cpp
new file mode 100644 (file)
index 0000000..d2c007f
--- /dev/null
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -triple x86_64-windows -fdiagnostics-format msvc -fno-rtti-data -fsyntax-only -verify
+
+namespace std {
+struct type_info {};
+} // namespace std
+class B {
+public:
+  virtual ~B() = default;
+};
+
+class D1 : public B {
+public:
+  ~D1() = default;
+};
+
+void f() {
+  B* b = new D1();
+  auto d = dynamic_cast<D1 *>(b); // expected-warning{{dynamic_cast will not work since RTTI data is disabled by /GR-}}
+  void* v = dynamic_cast<void *>(b); // expected-warning{{dynamic_cast will not work since RTTI data is disabled by /GR-}}
+  (void)typeid(int);              // expected-warning{{typeid will not work since RTTI data is disabled by /GR-}}
+}
diff --git a/clang/test/SemaCXX/no_dynamic_cast.cpp b/clang/test/SemaCXX/no_dynamic_cast.cpp
new file mode 100644 (file)
index 0000000..4db21d3
--- /dev/null
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -fno-rtti-data -fsyntax-only -verify
+
+namespace std {
+struct type_info {};
+} // namespace std
+class B {
+public:
+  virtual ~B() = default;
+};
+
+class D1 : public B {
+public:
+  ~D1() = default;
+};
+
+void f() {
+  B* b = new D1();
+  auto d = dynamic_cast<D1 *>(b); // expected-warning{{dynamic_cast will not work since RTTI data is disabled by -fno-rtti-data}}
+  void* v = dynamic_cast<void *>(b);
+  (void)typeid(int);              // expected-warning{{typeid will not work since RTTI data is disabled by -fno-rtti-data}}
+}