summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2009-11-24 17:14:34 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2009-11-24 17:14:34 +0000
commit03b67ea1a29c6d0dfcdbb0c18e73bd0850e9820b (patch)
tree0345053e5118586a2b9c2472cccc3ce73be419d5 /clang
parentdcf1962405ad1569230bbb145a26a9bc187c5cf9 (diff)
downloadbcm5719-llvm-03b67ea1a29c6d0dfcdbb0c18e73bd0850e9820b.tar.gz
bcm5719-llvm-03b67ea1a29c6d0dfcdbb0c18e73bd0850e9820b.zip
Make sure redeclaration chains are properly linked, even through invalid decls. This fixes PR5415.
llvm-svn: 89777
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/AST/Redeclarable.h12
-rw-r--r--clang/test/SemaCXX/class.cpp9
2 files changed, 19 insertions, 2 deletions
diff --git a/clang/include/clang/AST/Redeclarable.h b/clang/include/clang/AST/Redeclarable.h
index 867932332d0..35af8c766e9 100644
--- a/clang/include/clang/AST/Redeclarable.h
+++ b/clang/include/clang/AST/Redeclarable.h
@@ -92,6 +92,11 @@ public:
}
/// \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<decl_type>(
+ PrevDecl->getMostRecentDeclaration()));
First = PrevDecl->getFirstDeclaration();
assert(First->RedeclLink.NextIsLatest() && "Expected first");
} else {
diff --git a/clang/test/SemaCXX/class.cpp b/clang/test/SemaCXX/class.cpp
index d2a8114f7b0..302d1d58d39 100644
--- a/clang/test/SemaCXX/class.cpp
+++ b/clang/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}}
+};
OpenPOWER on IntegriCloud