mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-09-10 12:03:16 +02:00
Bug 520049 - Perform array-to-pointer conversion on operands of C conditional expression
Change-Id: Idd57bbcf12b7edf5c19fbd3debb8e64ea7851107
This commit is contained in:
parent
10b3a4ea3a
commit
08ea2dc248
5 changed files with 54 additions and 13 deletions
|
@ -7658,4 +7658,15 @@ public class AST2Tests extends AST2TestBase {
|
||||||
labelResolutionHelper(getAssertionHelper(C));
|
labelResolutionHelper(getAssertionHelper(C));
|
||||||
labelResolutionHelper(getAssertionHelper(CPP));
|
labelResolutionHelper(getAssertionHelper(CPP));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// int arr1[5];
|
||||||
|
// int arr2[5];
|
||||||
|
// void foo(bool cond) {
|
||||||
|
// cond ? arr1 : arr2;
|
||||||
|
// }
|
||||||
|
public void testArrayTypesInConditionalExpression_520049() throws Exception {
|
||||||
|
BindingAssertionHelper helper = getAssertionHelper(C);
|
||||||
|
IASTConditionalExpression expr = helper.assertNode("cond ? arr1 : arr2");
|
||||||
|
assertSameType(expr.getExpressionType(), CommonCTypes.pointerToInt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ public class SemanticTestBase extends BaseTestCase {
|
||||||
protected static class CommonCTypes {
|
protected static class CommonCTypes {
|
||||||
public static IType pointerToVoid = pointerTo(CBasicType.VOID);
|
public static IType pointerToVoid = pointerTo(CBasicType.VOID);
|
||||||
public static IType pointerToConstVoid = pointerTo(constOf(CBasicType.VOID));
|
public static IType pointerToConstVoid = pointerTo(constOf(CBasicType.VOID));
|
||||||
|
public static IType pointerToInt = pointerTo(CBasicType.INT);
|
||||||
public static IType pointerToConstInt = pointerTo(constOf(CBasicType.INT));
|
public static IType pointerToConstInt = pointerTo(constOf(CBasicType.INT));
|
||||||
public static IType pointerToVolatileInt = pointerTo(volatileOf(CBasicType.INT));
|
public static IType pointerToVolatileInt = pointerTo(volatileOf(CBasicType.INT));
|
||||||
public static IType pointerToConstVolatileInt = pointerTo(constVolatileOf(CBasicType.INT));
|
public static IType pointerToConstVolatileInt = pointerTo(constVolatileOf(CBasicType.INT));
|
||||||
|
|
|
@ -232,11 +232,11 @@ public class CASTBinaryExpression extends ASTNode
|
||||||
|
|
||||||
case IASTBinaryExpression.op_plus:
|
case IASTBinaryExpression.op_plus:
|
||||||
if (type1 instanceof IArrayType) {
|
if (type1 instanceof IArrayType) {
|
||||||
return arrayTypeToPointerType((ICArrayType) type1);
|
return Conversions.arrayTypeToPointerType((ICArrayType) type1);
|
||||||
} else if (type2 instanceof IPointerType) {
|
} else if (type2 instanceof IPointerType) {
|
||||||
return restoreTypedefs(type2, originalType2);
|
return restoreTypedefs(type2, originalType2);
|
||||||
} else if (type2 instanceof IArrayType) {
|
} else if (type2 instanceof IArrayType) {
|
||||||
return arrayTypeToPointerType((ICArrayType) type2);
|
return Conversions.arrayTypeToPointerType((ICArrayType) type2);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -252,13 +252,6 @@ public class CASTBinaryExpression extends ASTNode
|
||||||
return restoreTypedefs(type1, originalType1);
|
return restoreTypedefs(type1, originalType1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IType arrayTypeToPointerType(ICArrayType type) {
|
|
||||||
return new CPointerType(type.getType(),
|
|
||||||
(type.isConst() ? CPointerType.IS_CONST : 0) |
|
|
||||||
(type.isRestrict() ? CPointerType.IS_RESTRICT : 0) |
|
|
||||||
(type.isVolatile() ? CPointerType.IS_VOLATILE : 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLValue() {
|
public boolean isLValue() {
|
||||||
switch (getOperator()) {
|
switch (getOperator()) {
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.IBasicType;
|
||||||
import org.eclipse.cdt.core.dom.ast.ICompositeType;
|
import org.eclipse.cdt.core.dom.ast.ICompositeType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.c.ICArrayType;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
|
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
|
||||||
|
@ -198,6 +199,14 @@ public class CASTConditionalExpression extends ASTNode implements
|
||||||
return positiveType;
|
return positiveType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Perform array-to-pointer decay on the operand types.
|
||||||
|
if (positiveType instanceof ICArrayType) {
|
||||||
|
positiveType = Conversions.arrayTypeToPointerType(((ICArrayType) positiveType));
|
||||||
|
}
|
||||||
|
if (negativeType instanceof ICArrayType) {
|
||||||
|
negativeType = Conversions.arrayTypeToPointerType(((ICArrayType) negativeType));
|
||||||
|
}
|
||||||
|
|
||||||
// [6.5.15] p6: If both the second and third operands are pointers or one is a null pointer
|
// [6.5.15] p6: If both the second and third operands are pointers or one is a null pointer
|
||||||
// constant and the other is a pointer, the result type is a pointer to a type qualified with
|
// constant and the other is a pointer, the result type is a pointer to a type qualified with
|
||||||
|
@ -217,11 +226,12 @@ public class CASTConditionalExpression extends ASTNode implements
|
||||||
IType positivePointee = CVisitor.unwrapCV(positivePointeeCV);
|
IType positivePointee = CVisitor.unwrapCV(positivePointeeCV);
|
||||||
IType negativePointee = CVisitor.unwrapCV(negativePointeeCV);
|
IType negativePointee = CVisitor.unwrapCV(negativePointeeCV);
|
||||||
IType resultPointee;
|
IType resultPointee;
|
||||||
if (positivePointee.isSameType(CBasicType.VOID) || negativePointee.isSameType(CBasicType.VOID)) {
|
if (positivePointee.isSameType(negativePointee)) {
|
||||||
resultPointee = CBasicType.VOID;
|
|
||||||
} else {
|
|
||||||
// TODO: Implement checking for compatible types and computing the composite type.
|
|
||||||
resultPointee = negativePointee;
|
resultPointee = negativePointee;
|
||||||
|
} else if (positivePointee.isSameType(CBasicType.VOID) || negativePointee.isSameType(CBasicType.VOID)) {
|
||||||
|
resultPointee = CBasicType.VOID;
|
||||||
|
} else {
|
||||||
|
return ProblemType.UNKNOWN_FOR_EXPRESSION;
|
||||||
}
|
}
|
||||||
return new CPointerType(
|
return new CPointerType(
|
||||||
ExpressionTypes.restoreCV(resultPointee, positivePointeeCV, negativePointeeCV), 0);
|
ExpressionTypes.restoreCV(resultPointee, positivePointeeCV, negativePointeeCV), 0);
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2017 Nathan Ridge.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.dom.parser.c;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.c.ICArrayType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Routines related to conversions.
|
||||||
|
*/
|
||||||
|
public class Conversions {
|
||||||
|
/**
|
||||||
|
* Perform array-to-pointer decay.
|
||||||
|
*/
|
||||||
|
public static IType arrayTypeToPointerType(ICArrayType type) {
|
||||||
|
return new CPointerType(type.getType(),
|
||||||
|
(type.isConst() ? CPointerType.IS_CONST : 0) |
|
||||||
|
(type.isRestrict() ? CPointerType.IS_RESTRICT : 0) |
|
||||||
|
(type.isVolatile() ? CPointerType.IS_VOLATILE : 0));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue