1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-21 21:52:10 +02:00

Bug 542448 - Return ProblemBindings in list initialization

- Return ProblemBinding if conversion from init list failed
- In conversion: don't allow implicit conversion with explicit ctor

Change-Id: I3145b89df778a035ced9999aff4d8a4164eac17f
Signed-off-by: Hannes Vogt <hannes@havogt.de>
This commit is contained in:
Hannes Vogt 2018-12-05 22:54:33 +01:00 committed by Nathan Ridge
parent eb83237dc4
commit 945e48a40c
3 changed files with 73 additions and 5 deletions

View file

@ -148,6 +148,7 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPConstructor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethod; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethod;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
@ -4225,13 +4226,15 @@ public class AST2CPPTests extends AST2CPPTestBase {
} }
// class X { // class X {
// X(const X &); // public:
// X(const X &);
// }; // };
// class Y { // class Y {
// operator X (); // public:
// operator X();
// }; // };
// Y y; // Y y;
// X x = new X(y); // X* x = new X(y);
public void testBug90654a() throws Exception { public void testBug90654a() throws Exception {
IASTTranslationUnit tu = parse(getAboveComment(), CPP); IASTTranslationUnit tu = parse(getAboveComment(), CPP);
NameCollector col = new NameCollector(true); NameCollector col = new NameCollector(true);
@ -12777,4 +12780,58 @@ public class AST2CPPTests extends AST2CPPTestBase {
public void testElabSpecInTrailingReturn_535777() throws Exception { public void testElabSpecInTrailingReturn_535777() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// struct type {
// type(int,int){};
// };
//
// int main() {
// type a0(1,2);
// type a1{1,2};
// type a2 = {1,2};
// type a3(1,2,3);
// type a4{1,2,3};
// type a5 = {1,2,3};
// }
public void testInitListConstructor_542448() throws Exception {
BindingAssertionHelper bh = getAssertionHelper();
bh.assertImplicitName("a0", 2, CPPConstructor.class);
bh.assertImplicitName("a1", 2, CPPConstructor.class);
bh.assertImplicitName("a2", 2, CPPConstructor.class);
bh.assertImplicitName("a3", 2, IProblemBinding.class);
bh.assertImplicitName("a4", 2, IProblemBinding.class);
bh.assertImplicitName("a5", 2, IProblemBinding.class);
}
// struct type {
// explicit type(int,int){};
// };
//
// int main() {
// type a0(1,2); // ok
// type a1{1,2}; // ok
// type a2 = {1,2}; // error: using explict ctor
// }
public void testInitListConstructorWithExplicit_542448() throws Exception {
BindingAssertionHelper bh = getAssertionHelper();
bh.assertImplicitName("a0", 2, CPPConstructor.class);
bh.assertImplicitName("a1", 2, CPPConstructor.class);
bh.assertImplicitName("a2", 2, IProblemBinding.class);
}
// struct type {
// explicit type(int,int);
// type(float,float);
// };
// int main() {
// type a0 = {1,2};
// }
public void testInitListConstructorWithExplicit2_542448() throws Exception {
BindingAssertionHelper bh = getAssertionHelper();
// ill-formed, because overload resolution
// prefers the (int,int) constructor
// which is explicit
bh.assertImplicitName("a0", 2, IProblemBinding.class);
}
} }

View file

@ -3738,6 +3738,9 @@ public class CPPSemantics {
if (f instanceof ICPPConstructor) if (f instanceof ICPPConstructor)
return f; return f;
// If a conversion is used, the constructor is elided. // If a conversion is used, the constructor is elided.
} else {
return new ProblemBinding(null, typeId, ISemanticProblem.BINDING_NOT_FOUND,
type.getConstructors());
} }
} }
} else if (initializer instanceof ICPPASTInitializerList) { } else if (initializer instanceof ICPPASTInitializerList) {
@ -3749,6 +3752,9 @@ public class CPPSemantics {
ICPPFunction f = c.getUserDefinedConversion(); ICPPFunction f = c.getUserDefinedConversion();
if (f instanceof ICPPConstructor) if (f instanceof ICPPConstructor)
return f; return f;
} else {
return new ProblemBinding(null, typeId, ISemanticProblem.BINDING_NOT_FOUND,
type.getConstructors());
} }
} }
} else if (initializer instanceof ICPPASTConstructorInitializer) { } else if (initializer instanceof ICPPASTConstructorInitializer) {

View file

@ -728,11 +728,16 @@ public class Conversions {
} }
} }
} }
final IBinding result = CPPSemantics.resolveFunction(data, filteredConstructors, true, false); final IBinding result = CPPSemantics.resolveFunction(data, filteredConstructors, true, false);
final Cost c; final Cost c;
if (result instanceof ICPPMethod) { if (result instanceof ICPPMethod) {
c = new Cost(arg.getType(), t, Rank.IDENTITY); if (!isDirect && ((ICPPMethod) result).isExplicit()) {
c.setUserDefinedConversion((ICPPMethod) result); c = Cost.NO_CONVERSION;
} else {
c = new Cost(arg.getType(), t, Rank.IDENTITY);
c.setUserDefinedConversion((ICPPMethod) result);
}
} else if (result instanceof IProblemBinding } else if (result instanceof IProblemBinding
&& ((IProblemBinding) result).getID() == IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP) { && ((IProblemBinding) result).getID() == IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP) {
c = new Cost(arg.getType(), t, Rank.USER_DEFINED_CONVERSION); c = new Cost(arg.getType(), t, Rank.USER_DEFINED_CONVERSION);