diff options
author | Nathan Ridge | 2019-02-17 00:32:21 +0000 |
---|---|---|
committer | Nathan Ridge | 2019-03-01 01:45:43 +0000 |
commit | 4a35647d1f145ce64b5f07f0fba3681f5d3b359a (patch) | |
tree | c8a2f5930ebc945625a2a94e03c97bc8ee5fab89 | |
parent | 783af3dee625096e04cd7a162c3058d9d28451d1 (diff) | |
download | org.eclipse.cdt-4a35647d1f145ce64b5f07f0fba3681f5d3b359a.tar.gz org.eclipse.cdt-4a35647d1f145ce64b5f07f0fba3681f5d3b359a.tar.xz org.eclipse.cdt-4a35647d1f145ce64b5f07f0fba3681f5d3b359a.zip |
Bug 544509 - Evaluation of negative integer cast to unsigned
Change-Id: I683045870eca5f1b013afddbc0938df2aef779c2
2 files changed, 24 insertions, 1 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 90d4b2a7b7e..43a8fd83eb2 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 @@ -12719,6 +12719,12 @@ public class AST2CPPTests extends AST2CPPTestBase { helper.assertVariableValue("waldo", 1); } + // constexpr bool waldo = unsigned(-1) < unsigned(0); + public void testNegativeCastToUnsigned_544509() throws Exception { + BindingAssertionHelper helper = getAssertionHelper(); + helper.assertVariableValue("waldo", 0); + } + // namespace x { // void foo(); // } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java index 73b870c5fda..1d56670dd21 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java @@ -41,6 +41,7 @@ import org.eclipse.cdt.internal.core.dom.parser.CompositeValue; import org.eclipse.cdt.internal.core.dom.parser.DependentValue; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.IntegralValue; +import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; @@ -189,7 +190,23 @@ public class EvalTypeId extends CPPDependentEvaluation { } } if (fArguments.length == 1) { - return fArguments[0].getValue(); + IValue argVal = fArguments[0].getValue(); + if (argVal instanceof IntegralValue && argVal.numberValue() != null) { + // Cast signed integer to unsigned. + Long val = argVal.numberValue().longValue(); + if (val < 0 && inputType instanceof ICPPBasicType && ((ICPPBasicType) inputType).isUnsigned()) { + long sizeof = SizeofCalculator.getSizeAndAlignment(inputType).size; + if (sizeof > 4) { + // Java's "long" can't represent the full range of an 64-bit unsigned integer + // in C++. + sizeof = 4; + } + long range = (1L << (sizeof * 8 - 1)); + val += range; + return IntegralValue.create(val); + } + } + return argVal; } return IntegralValue.UNKNOWN; } |