forked from OSchip/llvm-project
[Sema][MSVC] warn at dynamic_cast/typeid when /GR- is given
Differential Revision: https://reviews.llvm.org/D86369
This commit is contained in:
parent
c4e589b795
commit
ebf267b87d
|
@ -1235,3 +1235,5 @@ in addition with the pragmas or -fmax-tokens flag to get any warnings.
|
||||||
}
|
}
|
||||||
|
|
||||||
def WebAssemblyExceptionSpec : DiagGroup<"wasm-exception-spec">;
|
def WebAssemblyExceptionSpec : DiagGroup<"wasm-exception-spec">;
|
||||||
|
|
||||||
|
def RTTI : DiagGroup<"rtti">;
|
||||||
|
|
|
@ -7451,6 +7451,12 @@ def err_no_typeid_with_fno_rtti : Error<
|
||||||
"use of typeid requires -frtti">;
|
"use of typeid requires -frtti">;
|
||||||
def err_no_dynamic_cast_with_fno_rtti : Error<
|
def err_no_dynamic_cast_with_fno_rtti : Error<
|
||||||
"use of dynamic_cast requires -frtti">;
|
"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<
|
def err_cannot_form_pointer_to_member_of_reference_type : Error<
|
||||||
"cannot form a pointer-to-member to member %0 of reference type %1">;
|
"cannot form a pointer-to-member to member %0 of reference type %1">;
|
||||||
|
|
|
@ -889,6 +889,18 @@ void CastOperation::CheckDynamicCast() {
|
||||||
return;
|
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.
|
// Done. Everything else is run-time checks.
|
||||||
Kind = CK_Dynamic;
|
Kind = CK_Dynamic;
|
||||||
}
|
}
|
||||||
|
|
|
@ -663,7 +663,16 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
|
||||||
}
|
}
|
||||||
|
|
||||||
// The operand is an expression.
|
// 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
|
/// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
Loading…
Reference in New Issue