From: Chandler Carruth Date: Fri, 29 Apr 2011 07:47:42 +0000 (+0000) Subject: Don't assume that the AST methods will only be invoked on C++ types. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5751838965eefa1c08e4fc545498a3ee45cd9611;p=clang Don't assume that the AST methods will only be invoked on C++ types. Teaches isLiteralType and isTrivialType to behave plausibly and most importantly not crash on normal RecordDecls. Sadly I have no real way to test this. I stumbled onto it by mis-implementing a warning. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130483 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index e75ce7dfe4..f4b34f0c06 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -891,22 +891,24 @@ bool Type::isLiteralType() const { if (BaseTy->isReferenceType()) return true; // -- a class type that has all of the following properties: if (const RecordType *RT = BaseTy->getAs()) { - const CXXRecordDecl *ClassDecl = cast(RT->getDecl()); - // -- a trivial destructor, - if (!ClassDecl->hasTrivialDestructor()) return false; - // -- every constructor call and full-expression in the - // brace-or-equal-initializers for non-static data members (if any) - // is a constant expression, - // FIXME: C++0x: Clang doesn't yet support non-static data member - // declarations with initializers, or constexprs. - // -- it is an aggregate type or has at least one constexpr - // constructor or constructor template that is not a copy or move - // constructor, and - if (!ClassDecl->isAggregate() && - !ClassDecl->hasConstExprNonCopyMoveConstructor()) - return false; - // -- all non-static data members and base classes of literal types - if (ClassDecl->hasNonLiteralTypeFieldsOrBases()) return false; + if (const CXXRecordDecl *ClassDecl = + dyn_cast(RT->getDecl())) { + // -- a trivial destructor, + if (!ClassDecl->hasTrivialDestructor()) return false; + // -- every constructor call and full-expression in the + // brace-or-equal-initializers for non-static data members (if any) + // is a constant expression, + // FIXME: C++0x: Clang doesn't yet support non-static data member + // declarations with initializers, or constexprs. + // -- it is an aggregate type or has at least one constexpr + // constructor or constructor template that is not a copy or move + // constructor, and + if (!ClassDecl->isAggregate() && + !ClassDecl->hasConstExprNonCopyMoveConstructor()) + return false; + // -- all non-static data members and base classes of literal types + if (ClassDecl->hasNonLiteralTypeFieldsOrBases()) return false; + } return true; } @@ -925,13 +927,14 @@ bool Type::isTrivialType() const { assert(BaseTy && "NULL element type"); if (BaseTy->isScalarType()) return true; if (const RecordType *RT = BaseTy->getAs()) { - const CXXRecordDecl *ClassDecl = cast(RT->getDecl()); - - // C++0x [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; + if (const CXXRecordDecl *ClassDecl = + dyn_cast(RT->getDecl())) { + // C++0x [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; + } return true; }