From 3e782bf8090c80e6d75e62cd52c9ed32715cbcdd Mon Sep 17 00:00:00 2001 From: Zequan Wu Date: Fri, 21 Aug 2020 13:42:20 -0700 Subject: [PATCH] [Sema][MSVC] warn at dynamic_cast when /GR- is given Differential Revision: https://reviews.llvm.org/D86369 --- clang/include/clang/Basic/DiagnosticGroups.td | 2 ++ .../clang/Basic/DiagnosticSemaKinds.td | 6 ++++++ clang/lib/Sema/SemaCast.cpp | 12 +++++++++++ clang/lib/Sema/SemaExprCXX.cpp | 6 ++++++ clang/test/SemaCXX/ms_no_dynamic_cast.cpp | 21 +++++++++++++++++++ clang/test/SemaCXX/no_dynamic_cast.cpp | 21 +++++++++++++++++++ 6 files changed, 68 insertions(+) create mode 100644 clang/test/SemaCXX/ms_no_dynamic_cast.cpp create mode 100644 clang/test/SemaCXX/no_dynamic_cast.cpp 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 d856f784e0ee..e1601da74b73 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -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; +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; 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 726900c59f20..b213fb756a65 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -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; } diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index d1fcdf354527..8f8847e63804 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -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 index 000000000000..d2c007fd8c29 --- /dev/null +++ b/clang/test/SemaCXX/ms_no_dynamic_cast.cpp @@ -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(b); // expected-warning{{dynamic_cast will not work since RTTI data is disabled by /GR-}} + void* v = dynamic_cast(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 index 000000000000..4db21d36f4a9 --- /dev/null +++ b/clang/test/SemaCXX/no_dynamic_cast.cpp @@ -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(b); // expected-warning{{dynamic_cast will not work since RTTI data is disabled by -fno-rtti-data}} + void* v = dynamic_cast(b); + (void)typeid(int); // expected-warning{{typeid will not work since RTTI data is disabled by -fno-rtti-data}} +}