[cfe-commits] r130492 - in /cfe/trunk: include/clang/AST/Type.h lib/AST/Type.cpp lib/Sema/SemaChecking.cpp test/SemaCXX/warn-non-pod-memset.cpp
Douglas Gregor
dgregor at apple.com
Fri Apr 29 07:48:22 PDT 2011
On Apr 29, 2011, at 2:46 AM, Chandler Carruth wrote:
> Author: chandlerc
> Date: Fri Apr 29 04:46:08 2011
> New Revision: 130492
>
> URL: http://llvm.org/viewvc/llvm-project?rev=130492&view=rev
> Log:
> Relax the non-POD memset warning to use the less restrictive C++11
> definition of POD. Specifically, this allows certain non-aggregate
> types due to their data members being private.
>
> The representation of C++11 POD testing is pretty gross. Any suggestions
> for improvements there are welcome. Especially the name
> 'isCXX11PODType()' seems truly unfortunate.
>
> Modified:
> cfe/trunk/include/clang/AST/Type.h
> cfe/trunk/lib/AST/Type.cpp
> cfe/trunk/lib/Sema/SemaChecking.cpp
> cfe/trunk/test/SemaCXX/warn-non-pod-memset.cpp
>
> Modified: cfe/trunk/include/clang/AST/Type.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=130492&r1=130491&r2=130492&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/Type.h (original)
> +++ cfe/trunk/include/clang/AST/Type.h Fri Apr 29 04:46:08 2011
> @@ -1179,6 +1179,12 @@
> /// (C++0x [basic.types]p9)
> bool isTrivialType() const;
>
> + /// isCXX11PODType() - Return true if this is a POD type according to the
> + /// more relaxed rules of the C++11 standard, regardless of the current
> + /// compilation's language.
> + /// (C++0x [basic.types]p9)
> + bool isCXX11PODType() const;
> +
> /// Helper methods to distinguish type categories. All type predicates
> /// operate on the canonical type, ignoring typedefs and qualifiers.
>
>
> Modified: cfe/trunk/lib/AST/Type.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=130492&r1=130491&r2=130492&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/Type.cpp (original)
> +++ cfe/trunk/lib/AST/Type.cpp Fri Apr 29 04:46:08 2011
> @@ -943,6 +943,52 @@
> return false;
> }
>
> +// This is effectively the intersection of isTrivialType and hasStandardLayout.
> +// We implement it dircetly to avoid redundant conversions from a type to
Typo "dircetly".
> +// a CXXRecordDecl.
> +bool Type::isCXX11PODType() const {
> + if (isIncompleteType())
> + return false;
Type::isPODType() handles incomplete arrays of POD types differently. Unless you have a reason to have a different result, I suggest following it.
> + // C++11 [basic.types]p9:
> + // Scalar types, POD classes, arrays of such types, and cv-qualified
> + // versions of these types are collectively called trivial types.
> + const Type *BaseTy = getBaseElementTypeUnsafe();
> + assert(BaseTy && "NULL element type");
> + if (BaseTy->isScalarType()) return true;
> + if (const RecordType *RT = BaseTy->getAs<RecordType>()) {
> + if (const CXXRecordDecl *ClassDecl =
> + dyn_cast<CXXRecordDecl>(RT->getDecl())) {
> + // C++11 [class]p10:
> + // A POD struct is a non-union class that is both a trivial class [...]
> + // C++11 [class]p5:
> + // A trivial class is a class that has a trivial default constructor
> + if (!ClassDecl->hasTrivialConstructor()) return false;
> + // and is trivially copyable.
> + if (!ClassDecl->isTriviallyCopyable()) return false;
> +
> + // C++11 [class]p10:
> + // A POD struct is a non-union class that is both a trivial class and
> + // a standard-layout class [...]
> + if (!ClassDecl->hasStandardLayout()) return false;
> +
> + // C++11 [class]p10:
> + // A POD struct is a non-union class that is both a trivial class and
> + // a standard-layout class, and has no non-static data members of type
> + // non-POD struct, non-POD union (or array of such types). [...]
> + //
> + // We don't directly query the recursive aspect as the requiremets for
> + // both standard-layout classes and trivial classes apply recursively
> + // already.
> + }
> +
> + return true;
> + }
You're not accounting for vector types here. How about following the implementation of Type::isPODType() more closely, or (better yet) factoring out the common checks so there's one isPODImpl(bool CXX0xSemantics)?
> + // No other types can match.
> + return false;
> +}
> +
> bool Type::isPromotableIntegerType() const {
> if (const BuiltinType *BT = getAs<BuiltinType>())
> switch (BT->getKind()) {
>
> Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=130492&r1=130491&r2=130492&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Apr 29 04:46:08 2011
> @@ -1812,21 +1812,34 @@
>
> 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->isPODType() && !PointeeTy->isVoidType()) {
> - DiagRuntimeBehavior(
> - Dest->getExprLoc(), Dest,
> - PDiag(diag::warn_non_pod_memset)
> - << 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*)"));
> - }
> + if (PointeeTy->isVoidType())
> + return;
> +
> + // Check the C++11 POD definition regardless of language mode; it is more
> + // relaxed than earlier definitions and we don't want spurrious warnings.
Typo "spurrious".
- Doug
More information about the cfe-commits
mailing list