# source:src/tests/polymorphism.c@1f370451

Last change on this file since 1f370451 was 1f370451, checked in by Rob Schluntz <rschlunt@…>, 7 years ago

Carry attributes through typedefs

• Property mode set to 100644
File size: 2.5 KB
Line
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// polymorphism.c --
8//
9// Author           : Rob Schluntz
10// Created On       : Tue Oct 17 12:19:48 2017
13// Update Count     : 1
14//
15
16#include <assert.h>
17#include <inttypes.h>
18
19forall(otype T)
20T f(T x, T y) {
21        x = y;
22        return x;
23}
24
25forall(otype T) T ident(T x) {
26        return x;
27}
28
29forall( otype T, otype U )
30size_t struct_size( T i, U j ) {
31        struct S { T i; U j; };
32        return sizeof(S);
33}
34
35forall( otype T, otype U )
36size_t union_size( T i, U j ) {
37        union B { T i; U j; };
38        return sizeof(B);
39}
40
41// perform some simple operations on aggregates of T and U
42forall( otype T | { void print(T); int ?==?(T, T); }, otype U | { void print(U); U ?=?(U&, zero_t); } )
43U foo(T i, U j) {
44        struct S { T i; U j; };
45        union B { T i; U j; };
46
47        S s;
48        s.i = i;
49        assertf(s.i == i, "struct operation fails in polymorphic context.");
50
51        B b;
52        b.j = 0;
53        b.i = s.i;
54        return b.j;
55}
56
57int main() {
58        {
59                // ensure that x is not changed by the invocation of a polymorphic function
60                int x = 123;
61                int y = 456;
62                int z = f(x, y);
63                printf("%d %d %d\n", x, y, z);
64        }
65
66        {
67                // explicitly specialize function
68                int (*f)(int) = ident;
69                ((int(*)(int))ident);
70                printf("%d %d\n", f(5), ((int(*)(int))ident)(5));
71        }
72
73        {
74                // test aggregates with polymorphic members
75                typedef __attribute__((aligned(8))) uint32_t x_type;
76                typedef __attribute__((aligned(8))) uint64_t y_type;
77
78                x_type x = 3;
79                y_type y = 3;
80
81                struct S {
82                        x_type f1;
83                        y_type f2;
84                };
85                union U {
86                        x_type f1;
87                        y_type f2;
88                };
89                // ensure that the size of aggregates with polymorphic members
90                // matches the size of the aggregates in a monomorphic context
91                size_t ssz = struct_size(x, y);
92                size_t usz = union_size(x, y);
93                assertf( ssz == sizeof(S), "struct size differs in polymorphic context: %zd / %zd", ssz, sizeof(S));
94                assertf( usz == sizeof(U), "union size differs in polymorphic context: %zd / %zd", usz, sizeof(U));
95
96                y_type ?=?(y_type & this, zero_t) {
97                        this = (int)0;
98                        return this;
99                }
100
101                void print(x_type x) {
102                        printf("%"PRIu32"\n", x);
103                }
104
105                void print(y_type y) {
106                        printf("%"PRIu64"\n", y);
107                }
108
109                y_type ret = foo(x, y);
110
111                // duplicate logic from inside of foo to ensure the same results
112                U u;
113                u.f2 = 0;
114                u.f1 = x;
115                assertf(ret == u.f2, "union operation fails in polymorphic context.");
116        }
117}
118
119// Local Variables: //
120// tab-width: 4 //
121// End: //
Note: See TracBrowser for help on using the repository browser.