Skip to main content
summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorHannes Vogt2019-03-28 03:10:34 -0400
committerHannes Vogt2019-04-02 02:08:41 -0400
commitd9550199f882e71343e3e2caa1e2c12360b84c64 (patch)
tree649920ba5deb9580e7578a3ef80ae65eeb5a4b7b /core
parentf85e3146d3fc62427d35ed8d61e6b13222c909e1 (diff)
downloadorg.eclipse.cdt-d9550199f882e71343e3e2caa1e2c12360b84c64.tar.gz
org.eclipse.cdt-d9550199f882e71343e3e2caa1e2c12360b84c64.tar.xz
org.eclipse.cdt-d9550199f882e71343e3e2caa1e2c12360b84c64.zip
Bug 545756 - Aggregate: init char array from literal
Implement [dcl.init.string] in aggregate initialization Change-Id: Ib6cf51cf08885dbfc281814c6521da3579301492 Signed-off-by: Hannes Vogt <hannes@havogt.de>
Diffstat (limited to 'core')
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java39
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AggregateInitialization.java72
2 files changed, 111 insertions, 0 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
index a1bdad7bcc..fc1f30c02c 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
@@ -13049,4 +13049,43 @@ public class AST2CPPTests extends AST2CPPTestBase {
BindingAssertionHelper bh = getAssertionHelper();
bh.assertImplicitName("b{v};", 1, IProblemBinding.class);
}
+
+ // struct type {
+ // char data[2];
+ // };
+ //
+ // type foo{"s"};
+ public void testCharArrayInitFromStringLiteral_545756() throws Exception {
+ parseAndCheckImplicitNameBindings();
+ }
+
+ // struct type {
+ // char data[3];
+ // };
+ //
+ // type foo{"big"};
+ public void testCharArrayInitFromTooLargeStringLiteral_545756() throws Exception {
+ BindingAssertionHelper bh = getAssertionHelper();
+ bh.assertImplicitName("foo", 3, IProblemBinding.class);
+ }
+
+ // struct type {
+ // char data[2];
+ // };
+ //
+ // type foo{L"s"};
+ public void testCharArrayInitFromWrongTypeStringLiteral_545756() throws Exception {
+ BindingAssertionHelper bh = getAssertionHelper();
+ bh.assertImplicitName("foo", 3, IProblemBinding.class);
+ }
+
+ // struct type {
+ // const char data[];
+ // };
+ //
+ // type foo{"s"};
+ public void testUnknownSizeCharArrayInitFromStringLiteral_545756() throws Exception {
+ BindingAssertionHelper bh = getAssertionHelper();
+ bh.assertImplicitName("foo", 3, IProblemBinding.class);
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AggregateInitialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AggregateInitialization.java
index 292a6886bf..64648a5231 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AggregateInitialization.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AggregateInitialization.java
@@ -11,12 +11,15 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IArrayType;
+import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.Context;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.UDCMode;
@@ -60,6 +63,7 @@ class AggregateInitialization {
* else recurses into the subaggregate.
*/
private Cost checkElement(IType type, IValue initialValue, Cost worstCost) throws DOMException {
+ assert !CPPTemplates.isDependentType(type);
IType nestedType = SemanticUtil.getNestedType(type, SemanticUtil.TDEF);
if (fIndex >= fInitializers.length)
// TODO for arrays we could short-circuit default init instead of trying to init each element
@@ -67,6 +71,30 @@ class AggregateInitialization {
worstCost = new Cost(fInitializers[fIndex].getType(), nestedType, Rank.IDENTITY);
ICPPEvaluation initializer = fInitializers[fIndex];
+ if (initFromStringLiteral(nestedType, initializer)) {
+ // [dcl.init.string]
+ fIndex++;
+ Number sizeOfCharArrayNumber = getArraySize(nestedType);
+ long sizeofCharArray = 0; // will error in case we cannot determine the size
+ if (sizeOfCharArrayNumber != null) {
+ sizeofCharArray = sizeOfCharArrayNumber.longValue();
+ }
+ Number sizeofStringLiteralNumber = getArraySize(initializer.getType());
+ long sizeofStringLiteral = Long.MAX_VALUE; // will error in case we cannot determine the size
+ if (sizeofStringLiteralNumber != null) {
+ sizeofStringLiteral = sizeofStringLiteralNumber.longValue();
+ }
+ IType targetCharType = getBasicTypeFromArray(nestedType);
+ IType literalCharType = getBasicTypeFromArray(initializer.getType());
+ Cost cost;
+ if (sizeofCharArray >= sizeofStringLiteral && targetCharType.isSameType(literalCharType)) {
+ cost = new Cost(initializer.getType(), nestedType, Rank.CONVERSION);
+ } else {
+ cost = Cost.NO_CONVERSION;
+ }
+ return cost;
+ }
+
Cost costWithoutElision = Conversions.checkImplicitConversionSequence(nestedType, initializer.getType(),
initializer.getValueCategory(), UDCMode.ALLOWED, Context.ORDINARY);
if (costWithoutElision.converts()) {
@@ -179,4 +207,48 @@ class AggregateInitialization {
return ArrayUtil.trim(result);
}
+ /**
+ * @param type
+ * @return CPPBasicType of element; null if type is not IArrayType or element is not CPPBasicType
+ */
+ private static ICPPBasicType getBasicTypeFromArray(IType type) {
+ if (type instanceof IArrayType) {
+ IType nested = SemanticUtil.getNestedType(((IArrayType) type).getType(), SemanticUtil.ALLCVQ);
+ if (nested instanceof ICPPBasicType) {
+ return (ICPPBasicType) nested;
+ }
+ }
+ return null;
+ }
+
+ private static boolean isCharArray(IType target) {
+ ICPPBasicType t = getBasicTypeFromArray(target);
+ if (t != null) {
+ Kind k = t.getKind();
+ return k == Kind.eChar || k == Kind.eChar16 || k == Kind.eChar32 || k == Kind.eWChar;
+ }
+ return false;
+ }
+
+ private static boolean fromStringLiteral(ICPPEvaluation initializer) {
+ ICPPBasicType t = getBasicTypeFromArray(initializer.getType());
+ if (t != null && t instanceof CPPBasicType) {
+ return ((CPPBasicType) t).isFromStringLiteral();
+ }
+ return false;
+ }
+
+ private static boolean initFromStringLiteral(IType target, ICPPEvaluation initializer) {
+ return isCharArray(target) && fromStringLiteral(initializer);
+ }
+
+ private static Number getArraySize(IType type) {
+ if (((IArrayType) type).getSize() != null) {
+ IValue size = ((IArrayType) type).getSize();
+ if (size.numberValue() != null) {
+ return ((IArrayType) type).getSize().numberValue();
+ }
+ }
+ return null;
+ }
} \ No newline at end of file

Back to the top