mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 01:36:01 +02:00
Bug 368611 - Bogus warning in template partial specialization
This commit is contained in:
parent
de2ec5102b
commit
af1c5c31d1
2 changed files with 59 additions and 2 deletions
|
@ -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.ICPPFunction;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
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.dom.parser.cpp.semantics.CPPVariableReadWriteFlags;
|
||||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
|
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
|
||||||
|
|
||||||
|
@ -171,9 +173,10 @@ public class ClassMembersInitializationChecker extends AbstractIndexAstChecker {
|
||||||
Set<IField> actualConstructorFields = constructorsStack.peek();
|
Set<IField> actualConstructorFields = constructorsStack.peek();
|
||||||
if (!actualConstructorFields.isEmpty()) {
|
if (!actualConstructorFields.isEmpty()) {
|
||||||
IBinding binding = name.resolveBinding();
|
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) {
|
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;
|
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
|
/** Checks whether class member of the specified type should be initialized
|
||||||
*
|
*
|
||||||
* @param type Type to check
|
* @param type Type to check
|
||||||
|
|
|
@ -543,4 +543,28 @@ public class ClassMembersInitializationCheckerTest extends CheckerTestCase {
|
||||||
loadCodeAndRun(getAboveComment());
|
loadCodeAndRun(getAboveComment());
|
||||||
checkNoErrors();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue