mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-22 06:02:11 +02:00
Bug 462705 - Derived-to-base pointer conversion in conditional operator
Change-Id: I04f792ae9485f9fbc67a7fd3658ef571d1ae7d0c Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
This commit is contained in:
parent
f93a835c69
commit
76f23d05c3
3 changed files with 55 additions and 22 deletions
|
@ -10652,6 +10652,19 @@ public class AST2CPPTests extends AST2TestBase {
|
|||
parseAndCheckBindings(getAboveComment(), CPP, true);
|
||||
}
|
||||
|
||||
// struct A {};
|
||||
//
|
||||
// struct B : A {};
|
||||
//
|
||||
// void foo(A*);
|
||||
//
|
||||
// int main() {
|
||||
// foo(true ? new A() : new B());
|
||||
// }
|
||||
public void testBasePointerConverstionInConditional_462705() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
|
||||
// template <bool>
|
||||
// struct enable_if {
|
||||
// };
|
||||
|
|
|
@ -1180,7 +1180,7 @@ public class Conversions {
|
|||
* Composite pointer type computed as described in 5.9-2 except that if the conversion to
|
||||
* the pointer is not possible, the method returns {@code null}.
|
||||
*/
|
||||
public static IType compositePointerType(IType t1, IType t2) {
|
||||
public static IType compositePointerType(IType t1, IType t2, IASTNode point) {
|
||||
final boolean isPtr1 = t1 instanceof IPointerType;
|
||||
if (isPtr1 || isNullPtr(t1)) {
|
||||
if (isNullPointerConstant(t2)) {
|
||||
|
@ -1210,7 +1210,7 @@ public class Conversions {
|
|||
return addQualifiers(p2, p1.isConst(), p1.isVolatile(), p1.isRestrict());
|
||||
}
|
||||
|
||||
IType t= mergePointers(target1, target2, true);
|
||||
IType t= mergePointers(target1, target2, point, true, true);
|
||||
if (t == null)
|
||||
return null;
|
||||
if (t == target1)
|
||||
|
@ -1220,7 +1220,7 @@ public class Conversions {
|
|||
return copyPointer(p1, t, false, false);
|
||||
}
|
||||
|
||||
private static IType mergePointers(IType t1, IType t2, boolean allcq) {
|
||||
private static IType mergePointers(IType t1, IType t2, IASTNode point, boolean allcq, boolean allowInheritance) {
|
||||
t1= getNestedType(t1, TDEF | REF);
|
||||
t2= getNestedType(t2, TDEF | REF);
|
||||
if (t1 instanceof IPointerType && t2 instanceof IPointerType) {
|
||||
|
@ -1234,7 +1234,7 @@ public class Conversions {
|
|||
return null;
|
||||
|
||||
final IType p1target = p1.getType();
|
||||
IType merged= mergePointers(p1target, p2.getType(), allcq && (cv1.isConst() || cv2.isConst()));
|
||||
IType merged= mergePointers(p1target, p2.getType(), point, allcq && (cv1.isConst() || cv2.isConst()), false);
|
||||
if (merged == null)
|
||||
return null;
|
||||
if (p1target == merged && cv1.isAtLeastAsQualifiedAs(cv2))
|
||||
|
@ -1247,9 +1247,11 @@ public class Conversions {
|
|||
|
||||
final IType uq1= getNestedType(t1, TDEF|REF|CVTYPE);
|
||||
final IType uq2= getNestedType(t2, TDEF|REF|CVTYPE);
|
||||
if (uq1 == null || ! uq1.isSameType(uq2))
|
||||
if (uq1 == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (uq1.isSameType(uq2)) {
|
||||
if (uq1 == t1 && uq2 == t2)
|
||||
return t1;
|
||||
|
||||
|
@ -1268,6 +1270,24 @@ public class Conversions {
|
|||
|
||||
// One type is const the other is volatile.
|
||||
return new CPPQualifierType(uq1, true, true);
|
||||
} else if (allowInheritance) {
|
||||
// Allow for conversion from pointer-to-derived to pointer-to-base as per [conv.ptr] p3.
|
||||
IType base;
|
||||
if (SemanticUtil.calculateInheritanceDepth(uq1, uq2, point) > 0) {
|
||||
base = uq2;
|
||||
} else if (SemanticUtil.calculateInheritanceDepth(uq2, uq1, point) > 0) {
|
||||
base = uq1;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
CVQualifier cv1= getCVQualifier(t1);
|
||||
CVQualifier cv2= getCVQualifier(t2);
|
||||
if (cv1 == CVQualifier.NONE && cv2 == CVQualifier.NONE) {
|
||||
return base;
|
||||
}
|
||||
return new CPPQualifierType(base, cv1.isConst() || cv2.isConst(), cv1.isVolatile() || cv2.isVolatile());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IType copyPointer(final IPointerType p1, IType target, final boolean isConst,
|
||||
|
|
|
@ -260,7 +260,7 @@ public class EvalConditional extends CPPDependentEvaluation {
|
|||
} else {
|
||||
fType= CPPArithmeticConversion.convertCppOperandTypes(IASTBinaryExpression.op_plus, t2, t3);
|
||||
if (fType == null) {
|
||||
fType= Conversions.compositePointerType(t2, t3);
|
||||
fType= Conversions.compositePointerType(t2, t3, point);
|
||||
if (fType == null) {
|
||||
fType= ProblemType.UNKNOWN_FOR_EXPRESSION;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue