summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-05-03 20:05:22 +0000
committerDouglas Gregor <dgregor@apple.com>2011-05-03 20:05:22 +0000
commita74926b518a766ef2d084cf5137b3aee88152f8a (patch)
treeb90b4cb1273de4fd398e0f7c39c09822df0ce629
parent0a9c1246d70ed63c24d8f44d5974040b8089034c (diff)
downloadbcm5719-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.td3
-rw-r--r--clang/lib/Sema/SemaChecking.cpp30
-rw-r--r--clang/test/SemaCXX/warn-non-pod-memset.cpp4
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}}
}
OpenPOWER on IntegriCloud