diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-08-28 22:03:51 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-08-28 22:03:51 +0000 |
commit | f3db00335894ca4c11263e36004527af43328ee0 (patch) | |
tree | 1e9da430a058dc75770543e21c7fad462dcdbcb2 | |
parent | 11395b66c6c59e8f68b4b00fc71aeacdd683911c (diff) | |
download | bcm5719-llvm-f3db00335894ca4c11263e36004527af43328ee0.tar.gz bcm5719-llvm-f3db00335894ca4c11263e36004527af43328ee0.zip |
Don't crash when instantiating templates containing anonymous structs/unions
llvm-svn: 80397
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 40 | ||||
-rw-r--r-- | clang/test/SemaTemplate/instantiate-anonymous-union.cpp | 8 |
2 files changed, 34 insertions, 14 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 732394d867d..7b06bf909aa 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1117,23 +1117,35 @@ static bool isInstantiationOf(ASTContext &Ctx, NamedDecl *D, Decl *Other) { if (D->getKind() != Other->getKind()) return false; - if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Other)) - return Record->getInstantiatedFromMemberClass()->getCanonicalDecl() - == D->getCanonicalDecl(); - - if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Other)) - return Function->getInstantiatedFromMemberFunction()->getCanonicalDecl() - == D->getCanonicalDecl(); + if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Other)) { + if (CXXRecordDecl *Pattern = Record->getInstantiatedFromMemberClass()) + return Pattern->getCanonicalDecl() == D->getCanonicalDecl(); + else + return false; + } + + if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Other)) { + if (FunctionDecl *Pattern = Function->getInstantiatedFromMemberFunction()) + return Pattern->getCanonicalDecl() == D->getCanonicalDecl(); + else + return false; + } - if (EnumDecl *Enum = dyn_cast<EnumDecl>(Other)) - return Enum->getInstantiatedFromMemberEnum()->getCanonicalDecl() - == D->getCanonicalDecl(); + if (EnumDecl *Enum = dyn_cast<EnumDecl>(Other)) { + if (EnumDecl *Pattern = Enum->getInstantiatedFromMemberEnum()) + return Pattern->getCanonicalDecl() == D->getCanonicalDecl(); + else + return false; + } if (VarDecl *Var = dyn_cast<VarDecl>(Other)) - if (Var->isStaticDataMember()) - return Var->getInstantiatedFromStaticDataMember()->getCanonicalDecl() - == D->getCanonicalDecl(); - + if (Var->isStaticDataMember()) { + if (VarDecl *Pattern = Var->getInstantiatedFromStaticDataMember()) + return Pattern->getCanonicalDecl() == D->getCanonicalDecl(); + else + return false; + } + // FIXME: How can we find instantiations of anonymous unions? return D->getDeclName() && isa<NamedDecl>(Other) && diff --git a/clang/test/SemaTemplate/instantiate-anonymous-union.cpp b/clang/test/SemaTemplate/instantiate-anonymous-union.cpp new file mode 100644 index 00000000000..4eb5b0c24cb --- /dev/null +++ b/clang/test/SemaTemplate/instantiate-anonymous-union.cpp @@ -0,0 +1,8 @@ +// RUN: clang-cc -fsyntax-only %s + +// FIXME: We need to test anonymous structs/unions in templates for real. + +template <typename T> class A { struct { }; }; + +A<int> a0; + |