summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2011-04-29 07:47:42 +0000
committerChandler Carruth <chandlerc@gmail.com>2011-04-29 07:47:42 +0000
commitefd5671a27e12dc8723be1d7b14fae45a8b0068b (patch)
tree9fe4522a6e90de6c5526a7727b719be15b6d75a7
parente1bd40cfbd618e1ebeba288e844d424df10c601d (diff)
downloadbcm5719-llvm-efd5671a27e12dc8723be1d7b14fae45a8b0068b.tar.gz
bcm5719-llvm-efd5671a27e12dc8723be1d7b14fae45a8b0068b.zip
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. llvm-svn: 130483
-rw-r--r--clang/lib/AST/Type.cpp49
1 files changed, 26 insertions, 23 deletions
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index e75ce7dfe40..f4b34f0c063 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/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<RecordType>()) {
- const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(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<CXXRecordDecl>(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<RecordType>()) {
- const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(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<CXXRecordDecl>(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;
}
OpenPOWER on IntegriCloud