[cfe-commits] r130786 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/Sema.h lib/Sema/SemaChecking.cpp test/SemaCXX/warn-non-pod-memset.cpp

Nico Weber thakis at chromium.org
Sun Jun 12 17:31:35 PDT 2011


Hi Doug,

(below)

On Tue, May 3, 2011 at 1:37 PM, Douglas Gregor <dgregor at apple.com> wrote:
> Author: dgregor
> Date: Tue May  3 15:37:33 2011
> New Revision: 130786
>
> URL: http://llvm.org/viewvc/llvm-project?rev=130786&view=rev
> Log:
> Extend -Wnon-pod-memset to also encompass memcpy() and memmove(),
> checking both the source and the destination operands, renaming the
> warning group to -Wnon-pod-memaccess and tweaking the diagnostic text
> in the process.
>
> Modified:
>    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>    cfe/trunk/include/clang/Sema/Sema.h
>    cfe/trunk/lib/Sema/SemaChecking.cpp
>    cfe/trunk/test/SemaCXX/warn-non-pod-memset.cpp
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=130786&r1=130785&r2=130786&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue May  3 15:37:33 2011
> @@ -261,13 +261,15 @@
>  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;
> -def note_non_pod_memset_silence : Note<
> +def warn_dyn_class_memaccess : Warning<
> +  "%select{destination for|source of}0 this %1 call is a pointer to dynamic "
> +  "class %2; vtable pointer will be overwritten">,
> +  InGroup<DiagGroup<"non-pod-memaccess">>;
> +def warn_non_pod_memaccess : Warning<
> +  "%select{destination for|source of}0 this %1 call is a pointer to non-POD "
> +  "type %2">,
> +  InGroup<DiagGroup<"non-pod-memaccess">>, DefaultIgnore;
> +def note_non_pod_memaccess_silence : Note<
>   "explicitly cast the pointer to silence this warning">;
>
>  /// main()
>
> Modified: cfe/trunk/include/clang/Sema/Sema.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=130786&r1=130785&r2=130786&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Sema/Sema.h (original)
> +++ cfe/trunk/include/clang/Sema/Sema.h Tue May  3 15:37:33 2011
> @@ -5552,7 +5552,8 @@
>                                  unsigned format_idx, unsigned firstDataArg,
>                                  bool isPrintf);
>
> -  void CheckMemsetArguments(const CallExpr *Call);
> +  void CheckMemsetcpymoveArguments(const CallExpr *Call,
> +                                   const IdentifierInfo *FnName);
>
>   void CheckReturnStackAddr(Expr *RetValExp, QualType lhsType,
>                             SourceLocation ReturnLoc);
>
> Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=130786&r1=130785&r2=130786&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaChecking.cpp Tue May  3 15:37:33 2011
> @@ -318,11 +318,13 @@
>                           TheCall->getCallee()->getLocStart());
>   }
>
> -  // Memset handling
> -  if (FnInfo->isStr("memset") &&
> -      FDecl->getLinkage() == ExternalLinkage &&
> -      (!getLangOptions().CPlusPlus || FDecl->isExternC()))
> -    CheckMemsetArguments(TheCall);
> +  // Memset/memcpy/memmove handling
> +  if (FDecl->getLinkage() == ExternalLinkage &&
> +      (!getLangOptions().CPlusPlus || FDecl->isExternC())) {
> +    if (FnInfo->isStr("memset") || FnInfo->isStr("memcpy") ||
> +        FnInfo->isStr("memmove"))
> +      CheckMemsetcpymoveArguments(TheCall, FnInfo);
> +  }
>
>   return false;
>  }
> @@ -1813,45 +1815,51 @@
>  /// \brief Check for dangerous or invalid arguments to memset().
>  ///
>  /// This issues warnings on known problematic or dangerous or unspecified
> -/// arguments to the standard 'memset' function call.
> +/// arguments to the standard 'memset', 'memcpy', and 'memmove' function calls.
>  ///
>  /// \param Call The call expression to diagnose.
> -void Sema::CheckMemsetArguments(const CallExpr *Call) {
> +void Sema::CheckMemsetcpymoveArguments(const CallExpr *Call,
> +                                       const IdentifierInfo *FnName) {
>   // It is possible to have a non-standard definition of memset.  Validate
>   // we have the proper number of arguments, and if not, abort further
>   // checking.
>   if (Call->getNumArgs() != 3)
>     return;
>
> -  const Expr *Dest = Call->getArg(0)->IgnoreParenImpCasts();
> -
> -  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 spurious warnings.
> -    else if (!PointeeTy->isCXX11PODType())
> -      DiagID = diag::warn_non_pod_memset;
> -    else
> -      return;
> +  unsigned LastArg = FnName->isStr("memset")? 1 : 2;
> +  for (unsigned ArgIdx = 0; ArgIdx != LastArg; ++ArgIdx) {
> +    const Expr *Dest = Call->getArg(ArgIdx)->IgnoreParenImpCasts();
> +
> +    QualType DestTy = Dest->getType();
> +    if (const PointerType *DestPtrTy = DestTy->getAs<PointerType>()) {
> +      QualType PointeeTy = DestPtrTy->getPointeeType();
> +      if (PointeeTy->isVoidType())
> +        continue;
> +
> +      unsigned DiagID = 0;
> +      // Always complain about dynamic classes.
> +      if (isDynamicClassType(PointeeTy))
> +        DiagID = diag::warn_dyn_class_memaccess;
> +      // Check the C++11 POD definition regardless of language mode; it is more
> +      // relaxed than earlier definitions and we don't want spurious warnings.
> +      else if (!PointeeTy->isCXX11PODType())
> +        DiagID = diag::warn_non_pod_memaccess;
> +      else
> +        continue;
>
> -    DiagRuntimeBehavior(
> -      Dest->getExprLoc(), Dest,
> -      PDiag(DiagID)
> -        << PointeeTy << Call->getCallee()->getSourceRange());
> -
> -    SourceRange ArgRange = Call->getArg(0)->getSourceRange();
> -    DiagRuntimeBehavior(
> -      Dest->getExprLoc(), Dest,
> -      PDiag(diag::note_non_pod_memset_silence)
> -        << FixItHint::CreateInsertion(ArgRange.getBegin(), "(void*)"));
> +      DiagRuntimeBehavior(
> +        Dest->getExprLoc(), Dest,
> +        PDiag(DiagID)
> +          << ArgIdx << FnName << PointeeTy
> +          << Call->getCallee()->getSourceRange());
> +
> +      SourceRange ArgRange = Call->getArg(0)->getSourceRange();

^ Should this be getArg(ArgIdx)?

> +      DiagRuntimeBehavior(
> +        Dest->getExprLoc(), Dest,
> +        PDiag(diag::note_non_pod_memaccess_silence)
> +          << FixItHint::CreateInsertion(ArgRange.getBegin(), "(void*)"));
> +      break;
> +    }
>   }
>  }
>
>
> Modified: cfe/trunk/test/SemaCXX/warn-non-pod-memset.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-non-pod-memset.cpp?rev=130786&r1=130785&r2=130786&view=diff
> ==============================================================================
> --- cfe/trunk/test/SemaCXX/warn-non-pod-memset.cpp (original)
> +++ cfe/trunk/test/SemaCXX/warn-non-pod-memset.cpp Tue May  3 15:37:33 2011
> @@ -1,6 +1,8 @@
> -// RUN: %clang_cc1 -fsyntax-only -Wnon-pod-memset -verify %s
> +// RUN: %clang_cc1 -fsyntax-only -Wnon-pod-memaccess -verify %s
>
>  extern "C" void *memset(void *, int, unsigned);
> +extern "C" void *memmove(void *s1, const void *s2, unsigned n);
> +extern "C" void *memcpy(void *s1, const void *s2, unsigned n);
>
>  // Several POD types that should not warn.
>  struct S1 {} s1;
> @@ -24,19 +26,32 @@
>
>  void test_warn() {
>   memset(&x1, 0, sizeof x1); // \
> -      // 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 non-POD type}} \
>       // expected-note {{explicitly cast the pointer to silence this warning}}
>   memset(&x2, 0, sizeof x2); // \
> -      // 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 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 dynamic class}} \
> +      // expected-warning {{destination for this 'memset' call is a pointer to 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-warning {{destination for this 'memset' call is a pointer to 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 dynamic class}} \
> +      // expected-warning {{destination for this 'memset' call is a pointer to dynamic class}} \
> +      // expected-note {{explicitly cast the pointer to silence this warning}}
> +
> +  memmove(&x1, 0, sizeof x1); // \
> +      // expected-warning{{destination for this 'memmove' call is a pointer to non-POD type 'struct X1'}} \
> +      // expected-note {{explicitly cast the pointer to silence this warning}}
> +  memmove(0, &x1, sizeof x1); // \
> +      // expected-warning{{source of this 'memmove' call is a pointer to non-POD type 'struct X1'}} \
> +      // expected-note {{explicitly cast the pointer to silence this warning}}
> +  memcpy(&x1, 0, sizeof x1); // \
> +      // expected-warning{{destination for this 'memcpy' call is a pointer to non-POD type 'struct X1'}} \
> +      // expected-note {{explicitly cast the pointer to silence this warning}}
> +  memcpy(0, &x1, sizeof x1); // \
> +      // expected-warning{{source of this 'memcpy' call is a pointer to non-POD type 'struct X1'}} \
>       // expected-note {{explicitly cast the pointer to silence this warning}}
>  }
>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>




More information about the cfe-commits mailing list