diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-05-03 20:05:22 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-05-03 20:05:22 +0000 |
commit | a74926b518a766ef2d084cf5137b3aee88152f8a (patch) | |
tree | b90b4cb1273de4fd398e0f7c39c09822df0ce629 | |
parent | 0a9c1246d70ed63c24d8f44d5974040b8089034c (diff) | |
download | bcm5719-llvm-a74926b518a766ef2d084cf5137b3aee88152f8a.tar.gz bcm5719-llvm-a74926b518a766ef2d084cf5137b3aee88152f8a.zip |
Separate the -Wnon-pod-memset warnings into two separate warnings:
- a default-on warning for pointers to dynamic classes (= classes with vtables)
- a default-off warning for other non-POD types
llvm-svn: 130781
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 30 | ||||
-rw-r--r-- | clang/test/SemaCXX/warn-non-pod-memset.cpp | 4 |
3 files changed, 25 insertions, 12 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index aa7f64a2466..7056fbc9283 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -261,6 +261,9 @@ def err_builtin_definition : Error<"definition of builtin function %0">; def err_types_compatible_p_in_cplusplus : Error< "__builtin_types_compatible_p is not valid in C++">; def warn_builtin_unknown : Warning<"use of unknown builtin %0">, DefaultError; +def warn_dyn_class_memset : Warning< + "destination for this memset call is a pointer to a dynamic class %0">, + InGroup<DiagGroup<"non-pod-memset">>; def warn_non_pod_memset : Warning< "destination for this memset call is a pointer to a non-POD type %0">, InGroup<DiagGroup<"non-pod-memset">>, DefaultIgnore; diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index ee1a924e5a1..76f20ce530c 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -1799,6 +1799,17 @@ void Sema::CheckFormatString(const StringLiteral *FExpr, //===--- CHECK: Standard memory functions ---------------------------------===// +/// \brief Determine whether the given type is a dynamic class type (e.g., +/// whether it has a vtable). +static bool isDynamicClassType(QualType T) { + if (CXXRecordDecl *Record = T->getAsCXXRecordDecl()) + if (CXXRecordDecl *Definition = Record->getDefinition()) + if (Definition->isDynamicClass()) + return true; + + return false; +} + /// \brief Check for dangerous or invalid arguments to memset(). /// /// This issues warnings on known problematic or dangerous or unspecified @@ -1814,27 +1825,26 @@ void Sema::CheckMemsetArguments(const CallExpr *Call) { const Expr *Dest = Call->getArg(0)->IgnoreParenImpCasts(); - // The type checking for this warning is moderately expensive, only do it - // when enabled. - if (getDiagnostics().getDiagnosticLevel(diag::warn_non_pod_memset, - Dest->getExprLoc()) == - Diagnostic::Ignored) - return; - QualType DestTy = Dest->getType(); if (const PointerType *DestPtrTy = DestTy->getAs<PointerType>()) { QualType PointeeTy = DestPtrTy->getPointeeType(); if (PointeeTy->isVoidType()) return; + unsigned DiagID = 0; + // Always complain about dynamic classes. + if (isDynamicClassType(PointeeTy)) + DiagID = diag::warn_dyn_class_memset; // Check the C++11 POD definition regardless of language mode; it is more - // relaxed than earlier definitions and we don't want spurrious warnings. - if (PointeeTy->isCXX11PODType()) + // relaxed than earlier definitions and we don't want spurious warnings. + else if (!PointeeTy->isCXX11PODType()) + DiagID = diag::warn_non_pod_memset; + else return; DiagRuntimeBehavior( Dest->getExprLoc(), Dest, - PDiag(diag::warn_non_pod_memset) + PDiag(DiagID) << PointeeTy << Call->getCallee()->getSourceRange()); SourceRange ArgRange = Call->getArg(0)->getSourceRange(); diff --git a/clang/test/SemaCXX/warn-non-pod-memset.cpp b/clang/test/SemaCXX/warn-non-pod-memset.cpp index 9023793bd52..6b017f338b0 100644 --- a/clang/test/SemaCXX/warn-non-pod-memset.cpp +++ b/clang/test/SemaCXX/warn-non-pod-memset.cpp @@ -30,13 +30,13 @@ void test_warn() { // expected-warning {{destination for this memset call is a pointer to a non-POD type}} \ // expected-note {{explicitly cast the pointer to silence this warning}} memset(&x3, 0, sizeof x3); // \ - // expected-warning {{destination for this memset call is a pointer to a non-POD type}} \ + // expected-warning {{destination for this memset call is a pointer to a dynamic class}} \ // expected-note {{explicitly cast the pointer to silence this warning}} memset(&x4, 0, sizeof x4); // \ // expected-warning {{destination for this memset call is a pointer to a non-POD type}} \ // expected-note {{explicitly cast the pointer to silence this warning}} memset(&x5, 0, sizeof x5); // \ - // expected-warning {{destination for this memset call is a pointer to a non-POD type}} \ + // expected-warning {{destination for this memset call is a pointer to a dynamic class}} \ // expected-note {{explicitly cast the pointer to silence this warning}} } |