Commit 004c383292

Andrew Kelley <superjoe30@gmail.com>
2018-09-24 18:19:16
fix translate-c incorrectly translating negative enum init values
closes #1360
1 parent 8a7737e
Changed files (2)
src/translate_c.cpp
@@ -458,7 +458,13 @@ static const char *decl_name(const Decl *decl) {
 static AstNode *trans_create_node_apint(Context *c, const llvm::APSInt &aps_int) {
     AstNode *node = trans_create_node(c, NodeTypeIntLiteral);
     node->data.int_literal.bigint = allocate<BigInt>(1);
-    bigint_init_data(node->data.int_literal.bigint, aps_int.getRawData(), aps_int.getNumWords(), aps_int.isNegative());
+    bool is_negative = aps_int.isNegative(); 
+    if (!is_negative) {
+        bigint_init_data(node->data.int_literal.bigint, aps_int.getRawData(), aps_int.getNumWords(), false);
+        return node;
+    }
+    llvm::APSInt negated = -aps_int;
+    bigint_init_data(node->data.int_literal.bigint, negated.getRawData(), negated.getNumWords(), true);
     return node;
 
 }
test/translate_c.zig
@@ -1,6 +1,60 @@
 const tests = @import("tests.zig");
 
 pub fn addCases(cases: *tests.TranslateCContext) void {
+    cases.add("negative enum init values",
+        \\enum EnumWithInits {
+        \\    VAL01 = 0,
+        \\    VAL02 = 1,
+        \\    VAL03 = 2,
+        \\    VAL04 = 3,
+        \\    VAL05 = -1,
+        \\    VAL06 = -2,
+        \\    VAL07 = -3,
+        \\    VAL08 = -4,
+        \\    VAL09 = VAL02 + VAL08,
+        \\    VAL10 = -1000012000,
+        \\    VAL11 = -1000161000,
+        \\    VAL12 = -1000174001,
+        \\    VAL13 = VAL09,
+        \\    VAL14 = VAL10,
+        \\    VAL15 = VAL11,
+        \\    VAL16 = VAL13,
+        \\    VAL17 = (VAL16 - VAL10 + 1),
+        \\    VAL18 = 0x1000000000000000L,
+        \\    VAL19 = VAL18 + VAL18 + VAL18 - 1,
+        \\    VAL20 = VAL19 + VAL19,
+        \\    VAL21 = VAL20 + 0xFFFFFFFFFFFFFFFF,
+        \\    VAL22 = 0xFFFFFFFFFFFFFFFF + 1,
+        \\    VAL23 = 0xFFFFFFFFFFFFFFFF,
+        \\};
+    ,
+        \\pub const enum_EnumWithInits = extern enum(c_longlong) {
+        \\    VAL01 = 0,
+        \\    VAL02 = 1,
+        \\    VAL03 = 2,
+        \\    VAL04 = 3,
+        \\    VAL05 = -1,
+        \\    VAL06 = -2,
+        \\    VAL07 = -3,
+        \\    VAL08 = -4,
+        \\    VAL09 = -3,
+        \\    VAL10 = -1000012000,
+        \\    VAL11 = -1000161000,
+        \\    VAL12 = -1000174001,
+        \\    VAL13 = -3,
+        \\    VAL14 = -1000012000,
+        \\    VAL15 = -1000161000,
+        \\    VAL16 = -3,
+        \\    VAL17 = 1000011998,
+        \\    VAL18 = 1152921504606846976,
+        \\    VAL19 = 3458764513820540927,
+        \\    VAL20 = 6917529027641081854,
+        \\    VAL21 = 6917529027641081853,
+        \\    VAL22 = 0,
+        \\    VAL23 = -1,
+        \\};
+    );
+
     cases.add("for loop with var init but empty body",
         \\void foo(void) {
         \\    for (int x = 0; x < 10; x++);