From 1cde4765bcd76ceefffbe22bf6d097c8a9a7144a Mon Sep 17 00:00:00 2001 From: Michael Schwarz Date: Thu, 16 Jan 2020 13:18:46 +0100 Subject: [PATCH] Add support for __imag__ References #8, References #9 --- src/check.ml | 7 ++++--- src/cil.ml | 8 ++++---- src/cil.mli | 4 ++-- src/frontc/cabs2cil.ml | 7 +++++-- test/small1/c99-complex.c | 6 ++++++ 5 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/check.ml b/src/check.ml index 12eba9005..22049f443 100644 --- a/src/check.ml +++ b/src/check.ml @@ -500,9 +500,10 @@ and checkExp (isconst: bool) (e: exp) : typ = | Real e -> let te = checkExp isconst e in - typeOfReal te - | Imag e -> E.s (E.bug "unimplemented") - + typeOfRealAndImagComponents te + | Imag e -> + let te = checkExp isconst e in + typeOfRealAndImagComponents te | AlignOf(t) -> begin (* Sizeof cannot be applied to certain types *) checkType t CTSizeof; diff --git a/src/cil.ml b/src/cil.ml index c14a95b84..59180456a 100755 --- a/src/cil.ml +++ b/src/cil.ml @@ -1597,8 +1597,8 @@ let isVoidPtrType t = TPtr(tau,_) when isVoidType tau -> true | _ -> false -(* get the typ of __real__(e) for e of typ t*) -let typeOfReal t = +(* get the typ of __real__(e) or __imag__(e) for e of typ t*) +let typeOfRealAndImagComponents t = match unrollType t with | TInt _ -> t | TFloat (fkind, attrs) -> @@ -1920,8 +1920,8 @@ let rec typeOf (e: exp) : typ = | Const(CReal (_, fk, _)) -> TFloat(fk, []) | Const(CEnum(tag, _, ei)) -> typeOf tag - | Real e -> typeOfReal @@ typeOf e - | Imag e -> E.s (E.bug "unsupported") + | Real e -> typeOfRealAndImagComponents @@ typeOf e + | Imag e -> typeOfRealAndImagComponents @@ typeOf e | Lval(lv) -> typeOfLval lv | SizeOf _ | SizeOfE _ | SizeOfStr _ -> !typeOfSizeOf | AlignOf _ | AlignOfE _ -> !typeOfSizeOf diff --git a/src/cil.mli b/src/cil.mli index b7a1aa7ee..8e453049b 100644 --- a/src/cil.mli +++ b/src/cil.mli @@ -1324,8 +1324,8 @@ val isVoidType: typ -> bool (** is the given type "void *"? *) val isVoidPtrType: typ -> bool -(** for numerical __complex types return type of corresponding real part *) -val typeOfReal: typ -> typ +(** for numerical __complex types return type of corresponding real part and imaginary parts *) +val typeOfRealAndImagComponents: typ -> typ (** for an fkind, return the corresponding complex fkind *) val getComplexFkind: fkind -> fkind diff --git a/src/frontc/cabs2cil.ml b/src/frontc/cabs2cil.ml index c18982873..de36604de 100644 --- a/src/frontc/cabs2cil.ml +++ b/src/frontc/cabs2cil.ml @@ -3658,8 +3658,11 @@ and doExp (asconst: bool) (* This expression is used as a constant *) | A.REAL e -> let (se, e', t) = doExp false e (AExp None) in let real = Real e' in - finishExp se real (typeOfReal t) - | A.IMAG e -> E.s (bug "cabs2cil: unsupported") + finishExp se real (typeOfRealAndImagComponents t) + | A.IMAG e -> + let (se, e', t) = doExp false e (AExp None) in + let imag = Imag e' in + finishExp se imag (typeOfRealAndImagComponents t) | A.CLASSIFYTYPE e -> let classify_type t = match unrollTypeDeep t with (* See gcc/typeclass.h *) diff --git a/test/small1/c99-complex.c b/test/small1/c99-complex.c index fdc6a7071..85ae7f4e4 100644 --- a/test/small1/c99-complex.c +++ b/test/small1/c99-complex.c @@ -29,10 +29,16 @@ int main(void) } double d = creal(x1); + double i = cimag(x1); + + double j = __imag__(1.0if); if(d != 0.5) E(2); + if(i != 1.0 || j != 1.0) + E(3); + double complex z1 = 1.0iF + 1; printf("I * I = %.1f%+.1fi\n", creal(z1), cimag(z1));