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:
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(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 {
|
||||
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));
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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