From 3fe4651e2ebc5f94dcefb0691c7bcd93ccd827d9 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Sun, 1 Jun 2008 22:53:53 +0000 Subject: [PATCH] fix decl attributes cleaning this plugs the leak of attributes and also fixes a crash in the test llvm-svn: 51862 --- clang/include/clang/AST/DeclBase.h | 1 + clang/lib/AST/Decl.cpp | 24 ++++++++++++++++-------- clang/lib/Sema/SemaDecl.cpp | 3 ++- clang/test/CodeGen/merge-attrs.c | 13 +++++++++++++ 4 files changed, 32 insertions(+), 9 deletions(-) create mode 100644 clang/test/CodeGen/merge-attrs.c diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 210f1691502c..b4f4c3b04651 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -136,6 +136,7 @@ public: void addAttr(Attr *attr); const Attr *getAttrs() const; void swapAttrs(Decl *D); + void invalidateAttrs(); template const T *getAttr() const { for (const Attr *attr = getAttrs(); attr; attr = attr->getNext()) diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 8d87d1cb4a25..8d9913b1aae9 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -336,14 +336,9 @@ Decl::~Decl() { DeclAttrMapTy::iterator it = DeclAttrs->find(this); assert(it != DeclAttrs->end() && "No attrs found but HasAttrs is true!"); - // FIXME: Properly release attributes. - // delete it->second; - DeclAttrs->erase(it); - - if (DeclAttrs->empty()) { - delete DeclAttrs; - DeclAttrs = 0; - } + // release attributes. + delete it->second; + invalidateAttrs(); } void Decl::addAttr(Attr *NewAttr) { @@ -358,6 +353,19 @@ void Decl::addAttr(Attr *NewAttr) { HasAttrs = true; } +void Decl::invalidateAttrs() { + if (!HasAttrs) return; + + HasAttrs = false; + (*DeclAttrs)[this] = 0; + DeclAttrs->erase(this); + + if (DeclAttrs->empty()) { + delete DeclAttrs; + DeclAttrs = 0; + } +} + const Attr *Decl::getAttrs() const { if (!HasAttrs) return 0; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index eb0abafcaaa2..230ea3cb9da7 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -276,7 +276,6 @@ static bool DeclHasAttr(const Decl *decl, const Attr *target) { static void MergeAttributes(Decl *New, Decl *Old) { Attr *attr = const_cast(Old->getAttrs()), *tmp; -// FIXME: fix this code to cleanup the Old attrs correctly while (attr) { tmp = attr; attr = attr->getNext(); @@ -288,6 +287,8 @@ static void MergeAttributes(Decl *New, Decl *Old) { delete(tmp); } } + + Old->invalidateAttrs(); } /// MergeFunctionDecl - We just parsed a function 'New' from diff --git a/clang/test/CodeGen/merge-attrs.c b/clang/test/CodeGen/merge-attrs.c new file mode 100644 index 000000000000..5ac0217e2b89 --- /dev/null +++ b/clang/test/CodeGen/merge-attrs.c @@ -0,0 +1,13 @@ +// RUN: clang %s -emit-llvm + +void *malloc(int size) __attribute__ ((__nothrow__)); + +inline static void __zend_malloc() { + malloc(1); +} + +void *malloc(int size) __attribute__ ((__nothrow__)); + +void fontFetch() { + __zend_malloc(1); +}