diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index 5e128e06319..c6aee05d55b 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -4198,6 +4198,11 @@ public class AST2CPPTests extends AST2BaseTest { } } + private void assertProblemBinding(int id, IBinding b) { + assertTrue(b instanceof IProblemBinding); + assertEquals(id, ((IProblemBinding) b).getID()); + } + protected void assertProblemBindings(CPPNameCollector col, int count) { Iterator i = col.nameList.iterator(); int sum = 0; @@ -6202,4 +6207,22 @@ public class AST2CPPTests extends AST2BaseTest { exstmt= getStatement(fdef, 1); assertInstance(exstmt.getExpression(), IASTBinaryExpression.class); } + + // template class A; + // class A {}; + // class A; + // class B; + // template class B; + // template class B {}; + public void testInvalidClassRedeclaration_254961() throws Exception { + final String code = getAboveComment(); + IASTTranslationUnit tu= parse(code, ParserLanguage.CPP, true, false); + CPPNameCollector nc= new CPPNameCollector(); + tu.accept(nc); + assertProblemBindings(nc, 4); + assertProblemBinding(IProblemBinding.SEMANTIC_INVALID_REDEFINITION, nc.getName(2).resolveBinding()); + assertProblemBinding(IProblemBinding.SEMANTIC_INVALID_REDECLARATION, nc.getName(3).resolveBinding()); + assertProblemBinding(IProblemBinding.SEMANTIC_INVALID_REDECLARATION, nc.getName(6).resolveBinding()); + assertProblemBinding(IProblemBinding.SEMANTIC_INVALID_REDEFINITION, nc.getName(8).resolveBinding()); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index 347b680899a..942d226eb25 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -1737,7 +1737,9 @@ public class CPPSemantics { } else { continue; } - + // select among those bindings that have been created without problems. + if (temp instanceof IProblemBinding) + continue; if (!(temp instanceof ICPPMember) && !declaredBefore) continue; if (temp instanceof ICPPUsingDeclaration) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index d7327833bb3..deb1168146d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -395,7 +395,12 @@ public class CPPVisitor extends ASTQueries { ASTInternal.addName(scope, elabType.getName()); } } else { - ((ICPPInternalBinding)binding).addDeclaration(elabType); + if ((binding instanceof ICPPClassTemplate) == template) { + ((ICPPInternalBinding)binding).addDeclaration(elabType); + } else { + binding = new ProblemBinding(name, + IProblemBinding.SEMANTIC_INVALID_REDECLARATION, name.toCharArray()); + } } } catch (DOMException e) { binding = e.getProblem(); @@ -435,7 +440,8 @@ public class CPPVisitor extends ASTQueries { } } else { ICPPInternalBinding internal = (ICPPInternalBinding) binding; - if (internal.getDefinition() == null) { + if (internal.getDefinition() == null && + (binding instanceof ICPPClassTemplate) == template) { internal.addDefinition(compType); } else { binding = new ProblemBinding(name,