Repository: Konstantin8105/c4go
Pull request #297 (2019-02-28 13:11:34)

transpileBinaryOperation: c type identification


Patch:
diff --git a/transpiler/binary.go b/transpiler/binary.go
index 4755ba9..ab12730 100644
--- a/transpiler/binary.go
+++ b/transpiler/binary.go
@@ -380,7 +380,7 @@ func transpileBinaryOperator(n *ast.BinaryOperator, p *program.Program, exprIsSt
 			// | `-DeclRefExpr 'char *' lvalue Var 0x26ba988 'c' 'char *'
 			// `-ImplicitCastExpr 'char *' <LValueToRValue>
 			//   `-DeclRefExpr 'char *' lvalue Var 0x26ba8a8 'b' 'char *'
-			if util.IsCPointer(leftType) {
+			if util.IsCPointer(leftType) || util.IsCArray(leftType) {
 				left = util.GetUintptr(left)
 				right = util.GetUintptr(right)
 				p.AddImport("unsafe")
diff --git a/transpiler/call.go b/transpiler/call.go
index e0c1e36..c20e880 100644
--- a/transpiler/call.go
+++ b/transpiler/call.go
@@ -190,9 +190,6 @@ func transpileCallExpr(n *ast.CallExpr, p *program.Program) (
 		if err != nil {
 			err = fmt.Errorf("Error in transpileCallExpr : %v", err)
 		}
-		if resultType == "" {
-			p.AddMessage(p.GenerateWarningMessage(fmt.Errorf("exprType is empty"), n))
-		}
 	}()
 
 	functionName, err := getName(p, n)
@@ -212,7 +209,7 @@ func transpileCallExpr(n *ast.CallExpr, p *program.Program) (
 		functionName == "__builtin_va_end" {
 		// ignore function __builtin_va_start, __builtin_va_end
 		// see "Variadic functions"
-		return nil, n.Type, nil, nil, nil
+		return nil, "", nil, nil, nil
 	}
 
 	// function "malloc" from stdlib.h
@@ -347,33 +344,9 @@ func transpileCallExpr(n *ast.CallExpr, p *program.Program) (
 			Name: functionName,
 		}
 		if len(n.Children()) > 0 {
-
-			checker := func(t string) bool {
-				return util.IsFunction(t) || types.IsTypedefFunction(p, t)
-			}
-
-			var finder func(n ast.Node) string
-			finder = func(n ast.Node) (t string) {
-				switch v := n.(type) {
-				case *ast.ImplicitCastExpr:
-					t = v.Type
-				case *ast.ParenExpr:
-					t = v.Type
-				case *ast.CStyleCastExpr:
-					t = v.Type
-				default:
-					panic(fmt.Errorf("add type %T", n))
-				}
-				if checker(t) {
-					return t
-				}
-				if len(n.Children()) == 0 {
-					return ""
-				}
-				return finder(n.Children()[0])
-			}
-
-			if t := finder(n.Children()[0]); checker(t) {
+			if v, ok := n.Children()[0].(*ast.ImplicitCastExpr); ok &&
+				(util.IsFunction(v.Type) || types.IsTypedefFunction(p, v.Type)) {
+				t := v.Type
 				if v, ok := p.TypedefType[t]; ok {
 					t = v
 				} else {
@@ -585,7 +558,7 @@ func transpileCallExpr(n *ast.CallExpr, p *program.Program) (
 			Rhs: []goast.Expr{realArgs[0]},
 		}
 		preStmts = append(preStmts, devNull)
-		return nil, n.Type, preStmts, postStmts, nil
+		return nil, "", preStmts, postStmts, nil
 	}
 
 	return util.NewCallExpr(functionName, realArgs...),
diff --git a/transpiler/operators.go b/transpiler/operators.go
index 32b7c56..277c3ba 100644
--- a/transpiler/operators.go
+++ b/transpiler/operators.go
@@ -59,14 +59,12 @@ func transpileConditionalOperator(n *ast.ConditionalOperator, p *program.Program
 
 	a, err = types.CastExpr(p, a, aType, "bool")
 	if err != nil {
-		err = fmt.Errorf("parameter `a` : %v", err)
 		return
 	}
 
 	// b - body
-	b, bType, newPre, newPost, err := atomicOperation(n.Children()[1], p)
+	b, bType, newPre, newPost, err := transpileToExpr(n.Children()[1], p, false)
 	if err != nil {
-		err = fmt.Errorf("parameter `b` : %v", err)
 		return
 	}
 	// Theorephly, length is must be zero
@@ -87,7 +85,6 @@ func transpileConditionalOperator(n *ast.ConditionalOperator, p *program.Program
 	// c - else body
 	c, cType, newPre, newPost, err := transpileToExpr(n.Children()[2], p, false)
 	if err != nil {
-		err = fmt.Errorf("parameter `c` : %v", err)
 		return nil, "", nil, nil, err
 	}
 	preStmts, postStmts = combinePreAndPostStmts(preStmts, postStmts, newPre, newPost)
@@ -95,7 +92,6 @@ func transpileConditionalOperator(n *ast.ConditionalOperator, p *program.Program
 	if n.Type != "void" {
 		c, err = types.CastExpr(p, c, cType, n.Type)
 		if err != nil {
-			err = fmt.Errorf("parameter `c` : %v", err)
 			return
 		}
 		cType = n.Type
@@ -553,9 +549,6 @@ func atomicOperation(n ast.Node, p *program.Program) (
 		if err != nil {
 			err = fmt.Errorf("Cannot create atomicOperation |%T|. err = %v", n, err)
 		}
-		if exprType == "" {
-			p.AddMessage(p.GenerateWarningMessage(fmt.Errorf("exprType is empty"), n))
-		}
 	}()
 
 	switch v := n.(type) {


Test patch:
diff --git a/tests/array.c b/tests/array.c
index edc70a7..e52c0e0 100644
--- a/tests/array.c
+++ b/tests/array.c
@@ -399,30 +399,9 @@ void test_parg_struct()
     is_streq(po_def[1].name, "optarg");
 }
 
-int function_array_field(int a)
-{
-	return a+1;
-}
-void test_function_array()
-{
-	struct fa {
-		int(* pf)(int);
-	};
-	struct fa f[10];
-	int i = 0;
-	for (i = 0; i < 10 ; i++)  {
-		f[i].pf = function_array_field;
-	}
-	int y = 42;
-	for (i = 0; i < 10; i++) {
-		y = ((f[i]).pf)(y);
-	}
-	is_eq(y , 52);
-}
-
 int main()
 {
-    plan(172);
+    plan(171);
 
     test_parg_struct();
     START_TEST(struct_init);
@@ -446,7 +425,6 @@ int main()
     START_TEST(ptrarr);
     START_TEST(stringarr_init);
     START_TEST(partialarr_init);
-    START_TEST(function_array);
 
     is_eq(arrayEx[1], 2.0);
 
diff --git a/tests/cast.c b/tests/cast.c
index 5234bb2..684d232 100644
--- a/tests/cast.c
+++ b/tests/cast.c
@@ -141,7 +141,7 @@ void test_unsafe_pnt()
 
 int main()
 {
-    plan(36);
+    plan(38);
 
     START_TEST(unsafe_pnt);
     START_TEST(bool_to_int);
@@ -257,6 +257,19 @@ int main()
             pass("long to bool")
         }
     }
+	diag("equal slice");
+	{
+		{
+			char n[10] = "hey";
+			char m[10] = "boy";
+			is_true( n != m );
+		}
+		{
+			char *n = "hey";
+			char *m = "boy";
+			is_true( n != m );
+		}
+	}
 
     char_overflow();