[clang] ebf267b - [Sema][MSVC] warn at dynamic_cast/typeid when /GR- is given

Zequan Wu via cfe-commits cfe-commits at lists.llvm.org
Wed Sep 16 10:39:01 PDT 2020


Author: Zequan Wu
Date: 2020-09-16T10:38:52-07:00
New Revision: ebf267b87d4b557dff488f87f66df3628e3da957

URL: https://github.com/llvm/llvm-project/commit/ebf267b87d4b557dff488f87f66df3628e3da957
DIFF: https://github.com/llvm/llvm-project/commit/ebf267b87d4b557dff488f87f66df3628e3da957.diff

LOG: [Sema][MSVC] warn at dynamic_cast/typeid when /GR- is given

Differential Revision: https://reviews.llvm.org/D86369

Added: 
    clang/test/SemaCXX/ms-no-rtti-data.cpp
    clang/test/SemaCXX/no-rtti-data.cpp

Modified: 
    clang/include/clang/Basic/DiagnosticGroups.td
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Sema/SemaCast.cpp
    clang/lib/Sema/SemaExprCXX.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 6b4dcc850612..a9bd52b8afcd 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -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">;

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index e0d700c66724..f6ded1b4ee26 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7451,6 +7451,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">;

diff  --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index f718154ce6db..d59f1880a7ff 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -889,6 +889,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;
 }

diff  --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index b5d4276f22b4..08b56413d8bf 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -663,7 +663,16 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
   }
 
   // The operand is an expression.
-  return BuildCXXTypeId(TypeInfoType, OpLoc, (Expr*)TyOrExpr, RParenLoc);
+  ExprResult Result =
+      BuildCXXTypeId(TypeInfoType, OpLoc, (Expr *)TyOrExpr, RParenLoc);
+
+  if (!getLangOpts().RTTIData && !Result.isInvalid())
+    if (auto *CTE = dyn_cast<CXXTypeidExpr>(Result.get()))
+      if (CTE->isPotentiallyEvaluated() && !CTE->isMostDerived(Context))
+        Diag(OpLoc, diag::warn_no_typeid_with_rtti_disabled)
+            << (getDiagnostics().getDiagnosticOptions().getFormat() ==
+                DiagnosticOptions::MSVC);
+  return Result;
 }
 
 /// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to

diff  --git a/clang/test/SemaCXX/ms-no-rtti-data.cpp b/clang/test/SemaCXX/ms-no-rtti-data.cpp
new file mode 100644
index 000000000000..aef167d8a373
--- /dev/null
+++ b/clang/test/SemaCXX/ms-no-rtti-data.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 %s -triple x86_64-windows-msvc -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);
+  (void)typeid(b);
+  (void)typeid(*b); // expected-warning{{typeid will not work since RTTI data is disabled by /GR-}}
+  B b2 = *b;
+  (void)typeid(b2);
+  (void)typeid(*&b2); // expected-warning{{typeid will not work since RTTI data is disabled by /GR-}}
+  (void)typeid((B &)b2);
+
+  B &br = b2;
+  (void)typeid(br); // expected-warning{{typeid will not work since RTTI data is disabled by /GR-}}
+  (void)typeid(&br);
+}
\ No newline at end of file

diff  --git a/clang/test/SemaCXX/no-rtti-data.cpp b/clang/test/SemaCXX/no-rtti-data.cpp
new file mode 100644
index 000000000000..af0dc7c11bb8
--- /dev/null
+++ b/clang/test/SemaCXX/no-rtti-data.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 %s -triple x86_64-unknown-linux -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);
+  (void)typeid(b);
+  (void)typeid(*b); // expected-warning{{typeid will not work since RTTI data is disabled by -fno-rtti-data}}
+  B b2 = *b;
+  (void)typeid(b2);
+  (void)typeid(*&b2); // expected-warning{{typeid will not work since RTTI data is disabled by -fno-rtti-data}}
+  (void)typeid((B &)b2);
+
+  B &br = b2;
+  (void)typeid(br); // expected-warning{{typeid will not work since RTTI data is disabled by -fno-rtti-data}}
+  (void)typeid(&br);
+}
\ No newline at end of file


        


More information about the cfe-commits mailing list