From 46408eedfff5aa33662cedb6716a20616f3bad31 Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Tue, 24 Nov 2009 17:14:34 +0000 Subject: [PATCH] Make sure redeclaration chains are properly linked, even through invalid decls. This fixes PR5415. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89777 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Redeclarable.h | 12 ++++++++++-- test/SemaCXX/class.cpp | 9 +++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/include/clang/AST/Redeclarable.h b/include/clang/AST/Redeclarable.h index 867932332d..35af8c766e 100644 --- a/include/clang/AST/Redeclarable.h +++ b/include/clang/AST/Redeclarable.h @@ -91,6 +91,11 @@ public: return D; } + /// \brief Returns the most recent (re)declaration of this declaration. + decl_type *getMostRecentDeclaration() { + return getFirstDeclaration()->RedeclLink.getNext(); + } + /// \brief Returns the most recent (re)declaration of this declaration. const decl_type *getMostRecentDeclaration() const { return getFirstDeclaration()->RedeclLink.getNext(); @@ -102,8 +107,11 @@ public: decl_type *First; if (PrevDecl) { - // Point to previous. - RedeclLink = PreviousDeclLink(PrevDecl); + // Point to previous. Make sure that this is actually the most recent + // redeclaration, or we can build invalid chains. If the most recent + // redeclaration is invalid, it won't be PrevDecl, but we want it anyway. + RedeclLink = PreviousDeclLink(cast( + PrevDecl->getMostRecentDeclaration())); First = PrevDecl->getFirstDeclaration(); assert(First->RedeclLink.NextIsLatest() && "Expected first"); } else { diff --git a/test/SemaCXX/class.cpp b/test/SemaCXX/class.cpp index d2a8114f7b..302d1d58d3 100644 --- a/test/SemaCXX/class.cpp +++ b/test/SemaCXX/class.cpp @@ -110,3 +110,12 @@ struct C4 { void f(); // expected-note{{previous declaration is here}} int f; // expected-error{{duplicate member 'f'}} }; + +// PR5415 - don't hang! +struct S +{ + void f(); // expected-note 2 {{previous declaration}} + // FIXME: the out-of-line error shouldn't be there + void S::f() {} // expected-error {{class member cannot be redeclared}} expected-error {{out-of-line}} expected-note {{previous definition}} + void f() {} // expected-error {{class member cannot be redeclared}} expected-error {{redefinition}} +}; -- 2.40.0