Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Ridge2017-07-30 03:42:20 +0000
committerNathan Ridge2017-08-08 04:52:06 +0000
commit08ea2dc248f4e262ac376c90b260193feee527f3 (patch)
treecb8c66fe292f22f980ee5a28ecf13a6341aeb5e9
parent10b3a4ea3ac7760a5372374677ae4dbd2879da44 (diff)
downloadorg.eclipse.cdt-08ea2dc248f4e262ac376c90b260193feee527f3.tar.gz
org.eclipse.cdt-08ea2dc248f4e262ac376c90b260193feee527f3.tar.xz
org.eclipse.cdt-08ea2dc248f4e262ac376c90b260193feee527f3.zip
Bug 520049 - Perform array-to-pointer conversion on operands of C conditional expression
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java11
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/SemanticTestBase.java1
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTBinaryExpression.java11
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTConditionalExpression.java18
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/Conversions.java26
5 files changed, 54 insertions, 13 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java
index 10caf4e5477..d9e51074ed2 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java
@@ -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);
+ }
}
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/SemanticTestBase.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/SemanticTestBase.java
index fccc174b5d2..b33723d6f6a 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/SemanticTestBase.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/SemanticTestBase.java
@@ -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));
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTBinaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTBinaryExpression.java
index 8438c9d288b..96b3b0c08fd 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTBinaryExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTBinaryExpression.java
@@ -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()) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTConditionalExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTConditionalExpression.java
index 410dd600bb7..f558fb17594 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTConditionalExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTConditionalExpression.java
@@ -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);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/Conversions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/Conversions.java
new file mode 100644
index 00000000000..aa039f47147
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/Conversions.java
@@ -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));
+ }
+}

Back to the top