Skip to content

C translation doesn't correctly select operations based on types #263

@robdockins

Description

@robdockins

See:

transop1 :: Op1 a b -> C.Expr -> C.Expr
transop1 op e = case op of
Not -> (C..!) e
Abs _ -> funcall "abs" [e]
Sign _ -> funcall "copysign" [C.LitDouble 1.0, e]
Recip _ -> C.LitDouble 1.0 C../ e
Exp _ -> funcall "exp" [e]
Sqrt _ -> funcall "sqrt" [e]
Log _ -> funcall "log" [e]
Sin _ -> funcall "sin" [e]
Tan _ -> funcall "tan" [e]
Cos _ -> funcall "cos" [e]
Asin _ -> funcall "asin" [e]
Atan _ -> funcall "atan" [e]
Acos _ -> funcall "acos" [e]
Sinh _ -> funcall "sinh" [e]
Tanh _ -> funcall "tanh" [e]
Cosh _ -> funcall "cosh" [e]
Asinh _ -> funcall "asinh" [e]
Atanh _ -> funcall "atanh" [e]
Acosh _ -> funcall "acosh" [e]
BwNot _ -> (C..~) e
Cast _ ty -> C.Cast (transtypename ty) e
GetField (Struct _) _ f -> C.Dot e (accessorname f)
-- | Translates a Copilot binary operator and its arguments into a C99
-- expression.
transop2 :: Op2 a b c -> C.Expr -> C.Expr -> C.Expr
transop2 op e1 e2 = case op of
And -> e1 C..&& e2
Or -> e1 C..|| e2
Add _ -> e1 C..+ e2
Sub _ -> e1 C..- e2
Mul _ -> e1 C..* e2
Mod _ -> e1 C..% e2
Div _ -> e1 C../ e2
Fdiv _ -> e1 C../ e2
Pow _ -> funcall "pow" [e1, e2]
Logb _ -> funcall "log" [e2] C../ funcall "log" [e1]
Eq _ -> e1 C..== e2
Ne _ -> e1 C..!= e2
Le _ -> e1 C..<= e2
Ge _ -> e1 C..>= e2
Lt _ -> e1 C..< e2
Gt _ -> e1 C..> e2
BwAnd _ -> e1 C..& e2
BwOr _ -> e1 C..| e2
BwXor _ -> e1 C..^ e2
BwShiftL _ _ -> e1 C..<< e2
BwShiftR _ _ -> e1 C..>> e2
Index _ -> C.Index e1 e2

Code generation selects a function to call based only on the operation, without paying attention the type. This is almost certainly not what is desired. For example abs is a function on int, but is applied also to float and double values. This causes the C compiler to (silently (!)) perform numerical coercions to/from int. Instead the generator should select fabs or fabsf. Likewise choosing between copysign or copysignf, cos or cosf, etc.

The abs case for integer values is actually even tricker, as copilot uses the fixed-width intX_t types, but, as far as I know, the standard library does not provide operations for fixed-width types, but instead only provides abs, labs, and llabs for int, long and long long respectively. The Sign operation is also troublesome, as it applies also to integer operations on the copilot side, but has no corresponding C primitive that I know of. These may have to be provided as macros to get correct behavior.

Metadata

Metadata

Labels

CR:Status:ClosedAdmin only: Change request that has been completedCR:Type:BugAdmin only: Change request pertaining to error detected

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions