1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 17:35:35 +02:00

Bug 520049 - Perform array-to-pointer conversion on operands of C conditional expression

Change-Id: Idd57bbcf12b7edf5c19fbd3debb8e64ea7851107
This commit is contained in:
Nathan Ridge 2017-07-29 23:42:20 -04:00
parent 10b3a4ea3a
commit 08ea2dc248
5 changed files with 54 additions and 13 deletions

View file

@ -7658,4 +7658,15 @@ public class AST2Tests extends AST2TestBase {
labelResolutionHelper(getAssertionHelper(C));
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);
}
}

View file

@ -47,6 +47,7 @@ public class SemanticTestBase extends BaseTestCase {
protected static class CommonCTypes {
public static IType pointerToVoid = pointerTo(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 pointerToVolatileInt = pointerTo(volatileOf(CBasicType.INT));
public static IType pointerToConstVolatileInt = pointerTo(constVolatileOf(CBasicType.INT));

View file

@ -232,11 +232,11 @@ public class CASTBinaryExpression extends ASTNode
case IASTBinaryExpression.op_plus:
if (type1 instanceof IArrayType) {
return arrayTypeToPointerType((ICArrayType) type1);
return Conversions.arrayTypeToPointerType((ICArrayType) type1);
} else if (type2 instanceof IPointerType) {
return restoreTypedefs(type2, originalType2);
} else if (type2 instanceof IArrayType) {
return arrayTypeToPointerType((ICArrayType) type2);
return Conversions.arrayTypeToPointerType((ICArrayType) type2);
}
break;
@ -252,13 +252,6 @@ public class CASTBinaryExpression extends ASTNode
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
public boolean isLValue() {
switch (getOperator()) {

View file

@ -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.IPointerType;
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.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
@ -198,6 +199,14 @@ public class CASTConditionalExpression extends ASTNode implements
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
// 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 negativePointee = CVisitor.unwrapCV(negativePointeeCV);
IType resultPointee;
if (positivePointee.isSameType(CBasicType.VOID) || negativePointee.isSameType(CBasicType.VOID)) {
resultPointee = CBasicType.VOID;
} else {
// TODO: Implement checking for compatible types and computing the composite type.
if (positivePointee.isSameType(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(
ExpressionTypes.restoreCV(resultPointee, positivePointeeCV, negativePointeeCV), 0);

View file

@ -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));
}
}