diff options
author | Marc-Andre Laperle | 2012-05-13 17:45:31 +0000 |
---|---|---|
committer | Marc-Andre Laperle | 2012-05-13 17:45:31 +0000 |
commit | af1c5c31d1dd6ec111ed9262ca8fdbcb22e2e37f (patch) | |
tree | 96af7156e3a2c970fc10e04dfe8fe3a70af785d5 | |
parent | de2ec5102b69a4e45a7cdc0ae04f27a018923229 (diff) | |
download | org.eclipse.cdt-af1c5c31d1dd6ec111ed9262ca8fdbcb22e2e37f.tar.gz org.eclipse.cdt-af1c5c31d1dd6ec111ed9262ca8fdbcb22e2e37f.tar.xz org.eclipse.cdt-af1c5c31d1dd6ec111ed9262ca8fdbcb22e2e37f.zip |
Bug 368611 - Bogus warning in template partial specialization
2 files changed, 59 insertions, 2 deletions
diff --git a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ClassMembersInitializationChecker.java b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ClassMembersInitializationChecker.java index f73999e63a0..96424e7596f 100644 --- a/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ClassMembersInitializationChecker.java +++ b/codan/org.eclipse.cdt.codan.checkers/src/org/eclipse/cdt/codan/internal/checkers/ClassMembersInitializationChecker.java @@ -43,6 +43,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; +import org.eclipse.cdt.core.index.IIndex; +import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVariableReadWriteFlags; import org.eclipse.cdt.internal.core.pdom.dom.PDOMName; @@ -171,9 +173,10 @@ public class ClassMembersInitializationChecker extends AbstractIndexAstChecker { Set<IField> actualConstructorFields = constructorsStack.peek(); if (!actualConstructorFields.isEmpty()) { IBinding binding = name.resolveBinding(); - if (actualConstructorFields.contains(binding)) { + IField equivalentFieldBinding = getContainedEquivalentBinding(actualConstructorFields, binding, name.getTranslationUnit().getIndex()); + if (equivalentFieldBinding != null) { if ((CPPVariableReadWriteFlags.getReadWriteFlags(name) & PDOMName.WRITE_ACCESS) != 0) { - actualConstructorFields.remove(binding); + actualConstructorFields.remove(equivalentFieldBinding); } } } @@ -181,6 +184,36 @@ public class ClassMembersInitializationChecker extends AbstractIndexAstChecker { return PROCESS_CONTINUE; } + private IField getContainedEquivalentBinding(Iterable<IField> fields, IBinding binding, IIndex index) { + for (IField field : fields) { + if (areEquivalentBindings(binding, field, index)) { + return field; + } + } + + return null; + } + + private boolean areEquivalentBindings(IBinding binding1, IBinding binding2, IIndex index) { + if (binding1.equals(binding2)) { + return true; + } + if ((binding1 instanceof IIndexBinding) != (binding2 instanceof IIndexBinding) && index != null) { + if (binding1 instanceof IIndexBinding) { + binding2 = index.adaptBinding(binding2); + } else { + binding1 = index.adaptBinding(binding1); + } + if (binding1 == null || binding2 == null) { + return false; + } + if (binding1.equals(binding2)) { + return true; + } + } + return false; + } + /** Checks whether class member of the specified type should be initialized * * @param type Type to check diff --git a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java index 55a23193970..40b6a97aa6f 100644 --- a/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java +++ b/codan/org.eclipse.cdt.codan.core.test/src/org/eclipse/cdt/codan/core/internal/checkers/ClassMembersInitializationCheckerTest.java @@ -543,4 +543,28 @@ public class ClassMembersInitializationCheckerTest extends CheckerTestCase { loadCodeAndRun(getAboveComment()); checkNoErrors(); } + + //@file:test.h + //template <typename> + //struct B; + + //@file:test.cpp + //#include "test.h" + // + //template <typename> + //struct A { + //}; + // + //template <typename valueT> + //struct B<A<valueT> > { + // const A<valueT>& obj; + // B(const A<valueT>& o) : obj(o) {} + //}; + public void testBug368611_templatePartialSpecialization() throws Exception { + CharSequence[] code = getContents(2); + loadcode(code[0].toString()); + loadcode(code[1].toString()); + runOnProject(); + checkNoErrors(); + } } |