Changeset 2055098
- Timestamp:
- May 1, 2017, 1:40:13 PM (6 years ago)
- Branches:
- aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 5544465, ed8a0d2
- Parents:
- 12d3187 (diff), 13e2c54 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 9 added
- 1 deleted
- 38 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
.gitignore
r12d3187 r2055098 1 1 # build files 2 2 *.[ao] 3 *.pyc 3 4 4 5 # generated by configure -
doc/generic_types/evaluation/Makefile
r12d3187 r2055098 1 CC = gcc 1 2 CFA = cfa 2 3 DEPFLAGS = -MMD -MP … … 6 7 endif 7 8 CXXFLAGS = $(CFLAGS) --std=c++14 9 MAKEFILE_NAME = ${firstword ${MAKEFILE_LIST}} 8 10 9 .PHONY : all clean distclean run-c run-cpp run-cfa run11 .PHONY : all clean run-c run-cpp run-cfa run 10 12 11 all : c-bench cpp-bench cfa-bench cpp-vbench13 all : c-bench cpp-bench cpp-vbench cfa-bench 12 14 13 15 # rewrite object generation to auto-determine deps … … 17 19 18 20 c-%.o : c-%.c 19 c-%.o : c-%.c c-%.d20 21 $(COMPILE.c) $(OUTPUT_OPTION) -c $< 21 22 22 23 cpp-%.o : cpp-%.cpp 23 cpp-%.o : cpp-%.cpp cpp-%.d24 24 $(COMPILE.cpp) $(OUTPUT_OPTION) -c $< 25 25 26 26 cfa-%.o : cfa-%.c 27 cfa-%.o : cfa-%.c cfa-%.d28 27 $(COMPILE.cfa) $(OUTPUT_OPTION) -c $< 29 28 30 COBJS = c-stack.o c-pair.o c-print.o 31 CPPOBJS = 32 CPPVOBJS = cpp-vstack.o 33 CFAOBJS = cfa-stack.o cfa-pair.o cfa-print.o 29 COBJS = c-stack.o c-pair.o c-print.o c-bench.o 30 CPPOBJS = cpp-bench.o 31 CPPVOBJS = cpp-vstack.o cpp-vbench.o 32 CFAOBJS = cfa-stack.o cfa-pair.o cfa-print.o cfa-bench.o 34 33 35 CFILES = c-bench.c bench.h $(COBJS:.o=.h) $(COBJS:.o=.c) 36 CPPFILES = cpp-bench.cpp bench.hpp cpp-stack.hpp cpp-pair.hpp cpp-print.hpp 37 CPPVFILES = cpp-vbench.cpp bench.hpp object.hpp $(CPPVOBJS:.o=.hpp) $(CPPVOBJS:.o=.cpp) cpp-vprint.hpp 38 CFAFILES = cfa-bench.c bench.h $(CFAOBJS:.o=.h) $(CFAOBJS:.o=.c) 34 ${COBJS} ${CPPOBJS} ${CPPVOBJS} ${CFAOBJS} : ${MAKEFILE_NAME} 39 35 40 c-bench: c-bench.c c-bench.d $(COBJS) 41 $(COMPILE.c) -o $@ $< $(COBJS) $(LDFLAGS) 36 CFILES = bench.h $(patsubst c-bench.h,,$(COBJS:.o=.h)) $(COBJS:.o=.c) 37 CPPFILES = bench.hpp cpp-stack.hpp cpp-pair.hpp cpp-print.hpp $(CPPOBJS:.o=.cpp) 38 CPPVFILES = bench.hpp object.hpp cpp-vprint.hpp $(patsubst cpp-vbench.hpp,,$(CPPVOBJS:.o=.hpp)) $(CPPVOBJS:.o=.cpp) 39 CFAFILES = bench.h $(patsubst cfa-bench.h,,$(CFAOBJS:.o=.h)) $(CFAOBJS:.o=.c) 42 40 43 c pp-bench: cpp-bench.cpp cpp-bench.d $(CPPOBJS)44 $(COMPILE.c pp) -o $@ $< $(CPPOBJS) $(LDFLAGS)41 c-bench : $(COBJS) c-bench.o 42 $(COMPILE.c) $(LDFLAGS) $^ -o $@ 45 43 46 cpp- vbench: cpp-vbench.cpp cpp-vbench.d $(CPPVOBJS)47 $(COMPILE.cpp) -o $@ $< $(CPPVOBJS) $(LDFLAGS)44 cpp-bench : $(CPPOBJS) cpp-bench.o 45 $(COMPILE.cpp) $(LDFLAGS) $^ -o $@ 48 46 49 c fa-bench: cfa-bench.c cfa-bench.d $(CFAOBJS)50 $(COMPILE.c fa) -o $@ $< $(CFAOBJS) $(LDFLAGS)47 cpp-vbench : $(CPPVOBJS) cpp-vbench.o 48 $(COMPILE.cpp) $(LDFLAGS) $^ -o $@ 51 49 52 clean: 53 -rm $(COBJS) c-bench 54 -rm $(CPPOBJS) cpp-bench 55 -rm $(CPPVOBJS) cpp-vbench 56 -rm $(CFAOBJS) cfa-bench 50 cfa-bench : $(CFAOBJS) cfa-bench.o 51 $(COMPILE.cfa) $(LDFLAGS) $^ -o $@ 57 52 58 distclean: clean 59 -rm $(COBJS:.o=.d) c-bench.d 60 -rm $(CPPOBJS:.o=.d) cpp-bench.d 61 -rm $(CPPVOBJS:.o=.d) cpp-vbench.d 62 -rm $(CFAOBJS:.o=.d) cfa-bench.d 53 # include dependency files 54 -include $(COBJS:.o=.d) 55 -include $(CPPOBJS:.o=.d) 56 -include $(CPPVOBJS:.o=.d) 57 -include $(CFAOBJS:.o=.d) 63 58 64 run-c: c-bench 59 clean : 60 rm -f $(COBJS) $(COBJS:.o=.d) c-bench 61 rm -f $(CPPOBJS) $(CPPOBJS:.o=.d) cpp-bench 62 rm -f $(CPPVOBJS) $(CPPVOBJS:.o=.d) cpp-vbench 63 rm -f $(CFAOBJS) $(CFAOBJS:.o=.d) cfa-bench 64 65 run-c : c-bench 65 66 @echo 66 67 @echo '## C ##' 67 @/usr/bin/time -f 'max_memory:\t%M kilobytes' ./ c-bench68 @/usr/bin/time -f 'max_memory:\t%M kilobytes' ./$< 68 69 @printf 'source_size:\t%8d lines\n' `cat $(CFILES) | wc -l` 69 70 @printf 'redundant_type_annotations:%8d lines\n' `cat $(CFILES) | fgrep '/***/' -c` 70 @printf 'binary_size:\t%8d bytes\n' `stat -c %s c-bench`71 @printf 'binary_size:\t%8d bytes\n' `stat -c %s $<` 71 72 72 run-cfa: cfa-bench 73 run-cpp : cpp-bench 74 @echo 75 @echo '## C++ ##' 76 @/usr/bin/time -f 'max_memory:\t %M kilobytes' ./$< 77 @printf 'source_size:\t%8d lines\n' `cat $(CPPFILES) | wc -l` 78 @printf 'redundant_type_annotations:%8d lines\n' `cat $(CPPFILES) | fgrep '/***/' -c` 79 @printf 'binary_size:\t%8d bytes\n' `stat -c %s $<` 80 81 run-cppv : cpp-vbench 82 @echo 83 @echo '## C++obj ##' 84 @/usr/bin/time -f 'max_memory:\t%M kilobytes' ./$< 85 @printf 'source_size:\t%8d lines\n' `cat $(CPPVFILES) | wc -l` 86 @printf 'redundant_type_annotations:%8d lines\n' `cat $(CPPVFILES) | fgrep '/***/' -c` 87 @printf 'binary_size:\t%8d bytes\n' `stat -c %s $<` 88 89 run-cfa : cfa-bench 73 90 @echo 74 91 @echo '## Cforall ##' 75 @/usr/bin/time -f 'max_memory:\t %M kilobytes' ./ cfa-bench92 @/usr/bin/time -f 'max_memory:\t %M kilobytes' ./$< 76 93 @printf 'source_size:\t%8d lines\n' `cat $(CFAFILES) | wc -l` 77 94 @printf 'redundant_type_annotations:%8d lines\n' `cat $(CFAFILES) | fgrep '/***/' -c` 78 @printf 'binary_size:\t%8d bytes\n' `stat -c %s cfa-bench`95 @printf 'binary_size:\t%8d bytes\n' `stat -c %s $<` 79 96 80 run-cpp: cpp-bench 81 @echo 82 @echo '## C++ ##' 83 @/usr/bin/time -f 'max_memory:\t %M kilobytes' ./cpp-bench 84 @printf 'source_size:\t%8d lines\n' `cat $(CPPFILES) | wc -l` 85 @printf 'redundant_type_annotations:%8d lines\n' `cat $(CPPFILES) | fgrep '/***/' -c` 86 @printf 'binary_size:\t%8d bytes\n' `stat -c %s cpp-bench` 87 88 run-cppv: cpp-vbench 89 @echo 90 @echo '## C++obj ##' 91 @/usr/bin/time -f 'max_memory:\t%M kilobytes' ./cpp-vbench 92 @printf 'source_size:\t%8d lines\n' `cat $(CPPVFILES) | wc -l` 93 @printf 'redundant_type_annotations:%8d lines\n' `cat $(CPPVFILES) | fgrep '/***/' -c` 94 @printf 'binary_size:\t%8d bytes\n' `stat -c %s cpp-vbench` 95 96 run: run-c run-cfa run-cpp run-cppv 97 98 # so make doesn't fail without dependency files 99 %.d: ; 100 101 # so make won't delete dependency files 102 .PRECIOUS: %.d 103 104 # include dependency files 105 -include: $(COBJS:.o=.d) 106 -include: $(CPPOBJS:.o=.d) 107 -include: $(CFAOBJS:.o=.d) 108 -include: c-bench.d 109 -include: cpp-bench.d 110 -include: cfa-bench.d 97 run : run-c run-cfa run-cpp run-cppv -
doc/generic_types/evaluation/c-bench.c
r12d3187 r2055098 39 39 40 40 int main(int argc, char** argv) { 41 FILE * out = fopen(" c-out.txt", "w");41 FILE * out = fopen("/dev/null", "w"); 42 42 int maxi = 0, vali = 42; 43 43 struct stack si = new_stack(), ti; -
doc/generic_types/evaluation/c-stack.c
r12d3187 r2055098 11 11 void copy_stack(struct stack* s, const struct stack* t, void* (*copy)(const void*)) { 12 12 struct stack_node** crnt = &s->head; 13 struct stack_node* next = t->head; 14 while ( next ) { 13 for ( struct stack_node* next = t->head; next; next = next->next ) { 15 14 *crnt = malloc(sizeof(struct stack_node)); /***/ 16 15 **crnt = (struct stack_node){ copy(next->value) }; /***/ 17 16 crnt = &(*crnt)->next; 18 next = next->next;19 17 } 20 18 *crnt = 0; … … 22 20 23 21 void clear_stack(struct stack* s, void (*free_el)(void*)) { 24 struct stack_node* next = s->head; 25 while ( next ) { 22 for ( struct stack_node* next = s->head; next; ) { 26 23 struct stack_node* crnt = next; 27 24 next = crnt->next; -
doc/generic_types/evaluation/cfa-bench.c
r12d3187 r2055098 6 6 7 7 int main( int argc, char *argv[] ) { 8 FILE * out = fopen( " cfa-out.txt", "w" );8 FILE * out = fopen( "/dev/null", "w" ); 9 9 int maxi = 0, vali = 42; 10 10 stack(int) si, ti; -
doc/generic_types/evaluation/cfa-stack.c
r12d3187 r2055098 11 11 forall(otype T) void ?{}(stack(T)* s, stack(T) t) { 12 12 stack_node(T)** crnt = &s->head; 13 stack_node(T)* next = t.head; 14 while ( next ) { 13 for ( stack_node(T)* next = t.head; next; next = next->next ) { 15 14 *crnt = ((stack_node(T)*)malloc()){ next->value }; /***/ 16 15 stack_node(T)* acrnt = *crnt; 17 16 crnt = &acrnt->next; 18 next = next->next;19 17 } 20 18 *crnt = 0; … … 46 44 47 45 forall(otype T) void clear(stack(T)* s) { 48 stack_node(T)* next = s->head; 49 while ( next ) { 46 for ( stack_node(T)* next = s->head; next; ) { 50 47 stack_node(T)* crnt = next; 51 48 next = crnt->next; -
doc/generic_types/evaluation/cpp-bench.cpp
r12d3187 r2055098 7 7 8 8 int main(int argc, char** argv) { 9 std::ofstream out{" cpp-out.txt"};9 std::ofstream out{"/dev/null"}; 10 10 int maxi = 0, vali = 42; 11 11 stack<int> si, ti; -
doc/generic_types/evaluation/cpp-stack.hpp
r12d3187 r2055098 13 13 void copy(const stack<T>& o) { 14 14 node** crnt = &head; 15 node* next = o.head; 16 while ( next ) { 15 for ( node* next = o.head; next; next = next->next ) { 17 16 *crnt = new node{ next->value }; /***/ 18 17 crnt = &(*crnt)->next; 19 next = next->next;20 18 } 21 19 *crnt = nullptr; … … 23 21 public: 24 22 void clear() { 25 node* next = head; 26 while ( next ) { 23 for ( node* next = head; next; ) { 27 24 node* crnt = next; 28 25 next = crnt->next; -
doc/generic_types/evaluation/cpp-vbench.cpp
r12d3187 r2055098 7 7 8 8 int main(int argc, char** argv) { 9 std::ofstream out{" cpp-vout.txt"};9 std::ofstream out{"/dev/null"}; 10 10 integer maxi{ 0 }, vali{ 42 }; 11 11 stack si, ti; -
doc/generic_types/evaluation/cpp-vstack.cpp
r12d3187 r2055098 6 6 void stack::copy(const stack& o) { 7 7 node** crnt = &head; 8 node* next = o.head; 9 while ( next ) { 8 for ( node* next = o.head; next; next = next->next ) { 10 9 *crnt = new node{ *next->value }; 11 10 crnt = &(*crnt)->next; 12 next = next->next;13 11 } 14 12 *crnt = nullptr; … … 35 33 36 34 void stack::clear() { 37 node* next = head; 38 while ( next ) { 35 for ( node* next = head; next; ) { 39 36 node* crnt = next; 40 37 next = crnt->next; -
doc/generic_types/generic_types.tex
r12d3187 r2055098 232 232 int comp( const void * t1, const void * t2 ) { return *(double *)t1 < *(double *)t2 ? -1 : 233 233 *(double *)t2 < *(double *)t1 ? 1 : 0; } 234 double key = 5.0, vals[10] = { /* 10 floating-point values */ };234 double key = 5.0, vals[10] = { /* 10 sorted floating-point values */ }; 235 235 double * val = (double *)bsearch( &key, vals, 10, sizeof(vals[0]), comp ); $\C{// search sorted array}$ 236 236 \end{lstlisting} … … 354 354 One of the known shortcomings of standard C is that it does not provide reusable type-safe abstractions for generic data structures and algorithms. 355 355 Broadly speaking, there are three approaches to implement abstract data-structures in C. 356 One approach is to write bespoke data 356 One approach is to write bespoke data-structures for each context in which they are needed. 357 357 While this approach is flexible and supports integration with the C type-checker and tooling, it is also tedious and error-prone, especially for more complex data structures. 358 358 A second approach is to use @void *@--based polymorphism, \eg the C standard-library functions @bsearch@ and @qsort@; an approach which does allow reuse of code for common functionality. … … 542 542 \end{lstlisting} 543 543 where the tuple variable-name serves the same purpose as the parameter name(s). 544 Tuple variables can be composed of any types, except for array types, since array sizes are generally unknown .544 Tuple variables can be composed of any types, except for array types, since array sizes are generally unknown in C. 545 545 546 546 One way to access the tuple-variable components is with assignment or composition: … … 552 552 \begin{lstlisting} 553 553 [int, int] * p = &qr; $\C{// tuple pointer}$ 554 int rem = qr .1;$\C{// access remainder}$555 int quo = div( 13, 5 ) .0; $\C{// access quotient}$556 p ->0= 5; $\C{// change quotient}$557 bar( qr .1, qr ); $\C{// pass remainder and quotient/remainder}$558 rem = [42, div( 13, 5 )] .0.1; $\C{// access 2nd component of 1st component of tuple expression}$554 int rem = qr`.1`; $\C{// access remainder}$ 555 int quo = div( 13, 5 )`.0`; $\C{// access quotient}$ 556 p`->0` = 5; $\C{// change quotient}$ 557 bar( qr`.1`, qr ); $\C{// pass remainder and quotient/remainder}$ 558 rem = [42, div( 13, 5 )]`.0.1`; $\C{// access 2nd component of 1st component of tuple expression}$ 559 559 \end{lstlisting} 560 560 … … 616 616 This semantics means mass assignment differs from C cascading assignment (\eg @a = b = c@) in that conversions are applied in each individual assignment, which prevents data loss from the chain of conversions that can happen during a cascading assignment. 617 617 For example, @[y, x] = 3.14@ performs the assignments @y = 3.14@ and @x = 3.14@, yielding @y == 3.14@ and @x == 3@; 618 whereas C cascading assignment @y = x = 3.14@ performs the assignments @x = 3.14@ and @y = x@, yielding @3@ in @y@ and @x@.618 whereas, C cascading assignment @y = x = 3.14@ performs the assignments @x = 3.14@ and @y = x@, yielding @3@ in @y@ and @x@. 619 619 Finally, tuple assignment is an expression where the result type is the type of the left-hand side of the assignment, just like all other assignment expressions in C. 620 620 This example shows mass, multiple, and cascading assignment used in one expression: … … 742 742 \end{lstlisting} 743 743 Hence, function parameter and return lists are flattened for the purposes of type unification allowing the example to pass expression resolution. 744 This relaxation is possible by extending the thunk scheme described by 744 This relaxation is possible by extending the thunk scheme described by~\citet{Bilson03}. 745 745 Whenever a candidate's parameter structure does not exactly match the formal parameter's structure, a thunk is generated to specialize calls to the actual function: 746 746 \begin{lstlisting} … … 748 748 \end{lstlisting} 749 749 so the thunk provides flattening and structuring conversions to inferred functions, improving the compatibility of tuples and polymorphism. 750 These thunks take advantage of GCC C nested-functions to produce closures that have the usual function 750 These thunks take advantage of GCC C nested-functions to produce closures that have the usual function-pointer signature. 751 751 752 752 … … 829 829 \subsection{Implementation} 830 830 831 Tuples are implemented in the \CFA translator via a transformation into generic types.831 Tuples are implemented in the \CFA translator via a transformation into \emph{generic types}. 832 832 For each $N$, the first time an $N$-tuple is seen in a scope a generic type with $N$ type parameters is generated, \eg: 833 833 \begin{lstlisting} … … 1086 1086 Finally, we demonstrate that \CFA performance for some idiomatic cases is better than C and close to \CC, showing the design is practically applicable. 1087 1087 1088 There is ongoing work on a wide range of \CFA feature extensions, including reference types, exceptions, concurrent primitives and modules.1088 There is ongoing work on a wide range of \CFA feature extensions, including reference types, arrays with size, exceptions, concurrent primitives and modules. 1089 1089 (While all examples in the paper compile and run, a public beta-release of \CFA will take another 8--12 months to finalize these additional extensions.) 1090 1090 In addition, there are interesting future directions for the polymorphism design. … … 1092 1092 \CFA polymorphic functions use dynamic virtual-dispatch; 1093 1093 the runtime overhead of this approach is low, but not as low as inlining, and it may be beneficial to provide a mechanism for performance-sensitive code. 1094 Two promising approaches are an @inline@ annotation at polymorphic function call sites to create a template-specialization of the function (provided the code is visible) or placing an @inline@ annotation on polymorphic function-definitions to instantiate a specialized version for some set of types .1094 Two promising approaches are an @inline@ annotation at polymorphic function call sites to create a template-specialization of the function (provided the code is visible) or placing an @inline@ annotation on polymorphic function-definitions to instantiate a specialized version for some set of types (\CC template specialization). 1095 1095 These approaches are not mutually exclusive and allow performance optimizations to be applied only when necessary, without suffering global code-bloat. 1096 1096 In general, we believe separate compilation, producing smaller code, works well with loaded hardware-caches, which may offset the benefit of larger inlined-code. … … 1117 1117 Throughout, @/***/@ designates a counted redundant type annotation. 1118 1118 1119 \ medskip\noindent1119 \smallskip\noindent 1120 1120 \CFA 1121 1121 \begin{lstlisting}[xleftmargin=2\parindentlnth,aboveskip=0pt,belowskip=0pt] -
src/libcfa/concurrency/invoke.h
r12d3187 r2055098 38 38 }; 39 39 40 struct __ thread_stack_t {41 struct thread_desc* top;40 struct __condition_stack_t { 41 struct __condition_criterion_t * top; 42 42 }; 43 43 … … 48 48 struct thread_desc * pop_head( struct __thread_queue_t * ); 49 49 50 void ?{}( struct __ thread_stack_t * );51 void push( struct __ thread_stack_t *, struct thread_desc * );52 struct thread_desc * pop( struct __thread_stack_t * );50 void ?{}( struct __condition_stack_t * ); 51 void push( struct __condition_stack_t *, struct __condition_criterion_t * ); 52 struct __condition_criterion_t * pop( struct __condition_stack_t * ); 53 53 54 54 void ?{}(spinlock * this); … … 82 82 struct thread_desc * owner; // current owner of the monitor 83 83 struct __thread_queue_t entry_queue; // queue of threads that are blocked waiting for the monitor 84 struct __ thread_stack_t signal_stack; // stack of threads to run next once we exit the monitor84 struct __condition_stack_t signal_stack; // stack of conditions to run next once we exit the monitor 85 85 struct monitor_desc * stack_owner; // if bulk acquiring was used we need to synchronize signals with an other monitor 86 86 unsigned int recursion; // monitor routines can be called recursively, we need to keep track of that -
src/libcfa/concurrency/kernel
r12d3187 r2055098 55 55 //----------------------------------------------------------------------------- 56 56 // Processor 57 enum FinishOpCode { No_Action, Release, Schedule, Release_Schedule }; 57 enum FinishOpCode { No_Action, Release, Schedule, Release_Schedule, Release_Multi, Release_Multi_Schedule }; 58 59 //TODO use union, many of these fields are mutually exclusive (i.e. MULTI vs NOMULTI) 58 60 struct FinishAction { 59 61 FinishOpCode action_code; 60 62 thread_desc * thrd; 61 63 spinlock * lock; 64 spinlock ** locks; 65 unsigned short lock_count; 66 thread_desc ** thrds; 67 unsigned short thrd_count; 62 68 }; 63 69 static inline void ?{}(FinishAction * this) { -
src/libcfa/concurrency/kernel.c
r12d3187 r2055098 235 235 ScheduleThread( this->finish.thrd ); 236 236 } 237 else if( this->finish.action_code == Release_Multi ) { 238 for(int i = 0; i < this->finish.lock_count; i++) { 239 unlock( this->finish.locks[i] ); 240 } 241 } 242 else if( this->finish.action_code == Release_Multi_Schedule ) { 243 for(int i = 0; i < this->finish.lock_count; i++) { 244 unlock( this->finish.locks[i] ); 245 } 246 for(int i = 0; i < this->finish.thrd_count; i++) { 247 ScheduleThread( this->finish.thrds[i] ); 248 } 249 } 237 250 else { 238 251 assert(this->finish.action_code == No_Action); … … 335 348 this_processor->finish.lock = lock; 336 349 this_processor->finish.thrd = thrd; 350 suspend(); 351 } 352 353 void ScheduleInternal(spinlock ** locks, unsigned short count) { 354 this_processor->finish.action_code = Release_Multi; 355 this_processor->finish.locks = locks; 356 this_processor->finish.lock_count = count; 357 suspend(); 358 } 359 360 void ScheduleInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) { 361 this_processor->finish.action_code = Release_Multi_Schedule; 362 this_processor->finish.locks = locks; 363 this_processor->finish.lock_count = lock_count; 364 this_processor->finish.thrds = thrds; 365 this_processor->finish.thrd_count = thrd_count; 337 366 suspend(); 338 367 } … … 529 558 } 530 559 531 void ?{}( __ thread_stack_t * this ) {560 void ?{}( __condition_stack_t * this ) { 532 561 this->top = NULL; 533 562 } 534 563 535 void push( __ thread_stack_t * this, thread_desc* t ) {536 assert( t->next != NULL);564 void push( __condition_stack_t * this, __condition_criterion_t * t ) { 565 assert( !t->next ); 537 566 t->next = this->top; 538 567 this->top = t; 539 568 } 540 569 541 thread_desc * pop( __thread_stack_t * this ) {542 thread_desc* top = this->top;570 __condition_criterion_t * pop( __condition_stack_t * this ) { 571 __condition_criterion_t * top = this->top; 543 572 if( top ) { 544 573 this->top = top->next; -
src/libcfa/concurrency/kernel_private.h
r12d3187 r2055098 26 26 thread_desc * nextThread(cluster * this); 27 27 28 void ScheduleInternal( );28 void ScheduleInternal(void); 29 29 void ScheduleInternal(spinlock * lock); 30 30 void ScheduleInternal(thread_desc * thrd); 31 31 void ScheduleInternal(spinlock * lock, thread_desc * thrd); 32 void ScheduleInternal(spinlock ** locks, unsigned short count); 33 void ScheduleInternal(spinlock ** locks, unsigned short count, thread_desc ** thrds, unsigned short thrd_count); 32 34 33 35 //----------------------------------------------------------------------------- -
src/libcfa/concurrency/monitor
r12d3187 r2055098 46 46 //----------------------------------------------------------------------------- 47 47 // Internal scheduling 48 49 struct __condition_criterion_t { 50 bool ready; //Whether or not the criterion is met (True if met) 51 monitor_desc * target; //The monitor this criterion concerns 52 struct __condition_node_t * owner; //The parent node to which this criterion belongs 53 __condition_criterion_t * next; //Intrusive linked list Next field 54 }; 55 56 struct __condition_node_t { 57 thread_desc * waiting_thread; //Thread that needs to be woken when all criteria are met 58 __condition_criterion_t * criteria; //Array of criteria (Criterions are contiguous in memory) 59 unsigned short count; //Number of criterions in the criteria 60 __condition_node_t * next; //Intrusive linked list Next field 61 }; 62 63 struct __condition_blocked_queue_t { 64 __condition_node_t * head; 65 __condition_node_t ** tail; 66 }; 67 68 void ?{}( __condition_blocked_queue_t * ); 69 void append( __condition_blocked_queue_t *, __condition_node_t * ); 70 __condition_node_t * pop_head( __condition_blocked_queue_t * ); 71 48 72 struct condition { 49 __ thread_queue_t blocked;50 monitor_desc ** monitors; 51 unsigned short monitor_count; 73 __condition_blocked_queue_t blocked; //Link list which contains the blocked threads as-well as the information needed to unblock them 74 monitor_desc ** monitors; //Array of monitor pointers (Monitors are NOT contiguous in memory) 75 unsigned short monitor_count; //Number of monitors in the array 52 76 }; 53 77 -
src/libcfa/concurrency/monitor.c
r12d3187 r2055098 20 20 #include "libhdr.h" 21 21 22 void set_owner( monitor_desc * this, thread_desc * owner ) { 23 //Pass the monitor appropriately 24 this->owner = owner; 25 26 //We are passing the monitor to someone else, which means recursion level is not 0 27 this->recursion = owner ? 1 : 0; 28 } 22 //----------------------------------------------------------------------------- 23 // Forward declarations 24 static inline void set_owner( monitor_desc * this, thread_desc * owner ); 25 static inline thread_desc * next_thread( monitor_desc * this ); 26 27 static inline void lock_all( spinlock ** locks, unsigned short count ); 28 static inline void lock_all( monitor_desc ** source, spinlock ** /*out*/ locks, unsigned short count ); 29 static inline void unlock_all( spinlock ** locks, unsigned short count ); 30 static inline void unlock_all( monitor_desc ** locks, unsigned short count ); 31 32 static inline void save_recursion ( monitor_desc ** ctx, unsigned int * /*out*/ recursions, unsigned short count ); 33 static inline void restore_recursion( monitor_desc ** ctx, unsigned int * /*in */ recursions, unsigned short count ); 34 35 static inline thread_desc * check_condition( __condition_criterion_t * ); 36 static inline void brand_condition( condition * ); 37 static inline unsigned short insert_unique( thread_desc ** thrds, unsigned short end, thread_desc * val ); 38 39 //----------------------------------------------------------------------------- 40 // Enter/Leave routines 41 29 42 30 43 extern "C" { 31 void __enter_monitor_desc(monitor_desc * this , monitor_desc * leader) {44 void __enter_monitor_desc(monitor_desc * this) { 32 45 lock( &this->lock ); 33 46 thread_desc * thrd = this_thread(); 34 47 35 // //Update the stack owner 36 // this->stack_owner = leader; 37 38 LIB_DEBUG_PRINT_SAFE("Entering %p (o: %p, r: %i)\n", this, this->owner, this->recursion); 48 LIB_DEBUG_PRINT_SAFE("%p Entering %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion); 39 49 40 50 if( !this->owner ) { … … 61 71 62 72 // leave pseudo code : 63 // decrement level 64 // leve == 0 ? 65 // no : done 66 // yes : 67 // signal stack empty ? 68 // has leader : 69 // bulk acquiring means we don't own the signal stack 70 // ignore it but don't release the monitor 71 // yes : 72 // next in entry queue is new owner 73 // no : 74 // top of the signal stack is the owner 75 // context switch to him right away 76 // 77 void __leave_monitor_desc(monitor_desc * this, monitor_desc * leader) { 73 // TODO 74 void __leave_monitor_desc(monitor_desc * this) { 78 75 lock( &this->lock ); 79 76 80 LIB_DEBUG_PRINT_SAFE("Leaving %p (o: %p, r: %i)\n", this, this->owner, this->recursion);81 82 77 thread_desc * thrd = this_thread(); 83 assertf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", this->owner, thrd, this->recursion ); 78 79 LIB_DEBUG_PRINT_SAFE("%p Leaving %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion); 80 assertf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", thrd, this->owner, this->recursion ); 84 81 85 82 //Leaving a recursion level, decrement the counter … … 89 86 //it means we don't need to do anything 90 87 if( this->recursion != 0) { 91 // this->stack_owner = leader;92 88 unlock( &this->lock ); 93 89 return; 94 90 } 95 96 // //If we don't own the signal stack then just leave it to the owner 97 // if( this->stack_owner ) { 98 // this->stack_owner = leader; 99 // unlock( &this->lock ); 100 // return; 101 // } 102 103 //We are the stack owner and have left the last recursion level. 104 //We are in charge of passing the monitor 105 thread_desc * new_owner = 0; 106 107 //Check the signaller stack 108 new_owner = pop( &this->signal_stack ); 109 if( new_owner ) { 110 //The signaller stack is not empty, 111 //transfer control immediately 112 set_owner( this, new_owner ); 113 // this->stack_owner = leader; 114 ScheduleInternal( &this->lock, new_owner ); 115 return; 116 } 117 118 // No signaller thread 119 // Get the next thread in the entry_queue 120 new_owner = pop_head( &this->entry_queue ); 121 set_owner( this, new_owner ); 122 123 // //Update the stack owner 124 // this->stack_owner = leader; 91 92 thread_desc * new_owner = next_thread( this ); 125 93 126 94 //We can now let other threads in safely … … 133 101 134 102 static inline void enter(monitor_desc ** monitors, int count) { 135 __enter_monitor_desc( monitors[0], NULL ); 136 for(int i = 1; i < count; i++) { 137 __enter_monitor_desc( monitors[i], monitors[0] ); 103 for(int i = 0; i < count; i++) { 104 __enter_monitor_desc( monitors[i] ); 138 105 } 139 106 } 140 107 141 108 static inline void leave(monitor_desc ** monitors, int count) { 142 __leave_monitor_desc( monitors[0], NULL ); 143 for(int i = count - 1; i >= 1; i--) { 144 __leave_monitor_desc( monitors[i], monitors[0] ); 109 for(int i = count - 1; i >= 0; i--) { 110 __leave_monitor_desc( monitors[i] ); 145 111 } 146 112 } … … 169 135 // Internal scheduling 170 136 void wait( condition * this ) { 171 assertf(false, "NO SUPPORTED"); 172 // LIB_DEBUG_FPRINTF("Waiting\n"); 173 thread_desc * this_thrd = this_thread(); 174 175 if( !this->monitors ) { 176 this->monitors = this_thrd->current_monitors; 177 this->monitor_count = this_thrd->current_monitor_count; 178 } 137 LIB_DEBUG_PRINT_SAFE("Waiting\n"); 138 139 brand_condition( this ); 140 141 //Check that everything is as expected 142 assertf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors ); 143 assertf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count ); 179 144 180 145 unsigned short count = this->monitor_count; 181 182 //Check that everything is as expected183 assert( this->monitors != NULL );184 assert( this->monitor_count != 0 );185 186 146 unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 187 147 spinlock * locks [ count ]; //We need to pass-in an array of locks to ScheduleInternal 188 148 189 // LIB_DEBUG_FPRINTF("Getting ready to wait\n"); 190 191 //Loop on all the monitors and release the owner 192 for( unsigned int i = 0; i < count; i++ ) { 193 monitor_desc * cur = this->monitors[i]; 194 195 assert( cur ); 196 197 // LIB_DEBUG_FPRINTF("cur %p lock %p\n", cur, &cur->lock); 198 199 //Store the locks for later 200 locks[i] = &cur->lock; 201 202 //Protect the monitors 203 lock( locks[i] ); 204 { 205 //Save the recursion levels 206 recursions[i] = cur->recursion; 207 208 //Release the owner 209 cur->recursion = 0; 210 cur->owner = NULL; 211 } 212 //Release the monitor 213 unlock( locks[i] ); 214 } 215 216 // LIB_DEBUG_FPRINTF("Waiting now\n"); 217 218 //Everything is ready to go to sleep 219 ScheduleInternal( locks, count ); 149 LIB_DEBUG_PRINT_SAFE("count %i\n", count); 150 151 __condition_node_t waiter; 152 waiter.waiting_thread = this_thread(); 153 waiter.count = count; 154 waiter.next = NULL; 155 156 __condition_criterion_t criteria[count]; 157 for(int i = 0; i < count; i++) { 158 criteria[i].ready = false; 159 criteria[i].target = this->monitors[i]; 160 criteria[i].owner = &waiter; 161 criteria[i].next = NULL; 162 LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] ); 163 } 164 165 waiter.criteria = criteria; 166 append( &this->blocked, &waiter ); 167 168 lock_all( this->monitors, locks, count ); 169 save_recursion( this->monitors, recursions, count ); 170 //DON'T unlock, ask the kernel to do it 171 172 //Find the next thread(s) to run 173 unsigned short thread_count = count; 174 thread_desc * threads[ count ]; 175 176 for( int i = 0; i < count; i++) { 177 thread_desc * new_owner = next_thread( this->monitors[i] ); 178 thread_count = insert_unique( threads, i, new_owner ); 179 } 180 181 LIB_DEBUG_PRINT_SAFE("Will unblock: "); 182 for(int i = 0; i < thread_count; i++) { 183 LIB_DEBUG_PRINT_SAFE("%p ", threads[i]); 184 } 185 LIB_DEBUG_PRINT_SAFE("\n"); 186 187 // Everything is ready to go to sleep 188 ScheduleInternal( locks, count, threads, thread_count ); 220 189 221 190 … … 224 193 225 194 //We are back, restore the owners and recursions 226 for( unsigned int i = 0; i < count; i++ ) { 227 monitor_desc * cur = this->monitors[i]; 228 229 //Protect the monitors 230 lock( locks[i] ); 231 { 232 //Release the owner 233 cur->owner = this_thrd; 234 cur->recursion = recursions[i]; 235 } 236 //Release the monitor 237 unlock( locks[i] ); 238 } 239 } 240 241 static void __signal_internal( condition * this ) { 242 assertf(false, "NO SUPPORTED"); 243 if( !this->blocked.head ) return; 195 lock_all( locks, count ); 196 restore_recursion( this->monitors, recursions, count ); 197 unlock_all( locks, count ); 198 } 199 200 void signal( condition * this ) { 201 if( !this->blocked.head ) { 202 LIB_DEBUG_PRINT_SAFE("Nothing to signal\n"); 203 return; 204 } 244 205 245 206 //Check that everything is as expected 246 207 assert( this->monitors ); 247 208 assert( this->monitor_count != 0 ); 209 210 unsigned short count = this->monitor_count; 248 211 249 212 LIB_DEBUG_DO( 250 if ( this->monitors != this_thread()->current_monitors ) { 251 abortf( "Signal on condition %p made outside of the correct monitor(s)", this ); 213 thread_desc * this_thrd = this_thread(); 214 if ( this->monitor_count != this_thrd->current_monitor_count ) { 215 abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", this, this->monitor_count, this_thrd->current_monitor_count ); 252 216 } // if 217 218 for(int i = 0; i < this->monitor_count; i++) { 219 if ( this->monitors[i] != this_thrd->current_monitors[i] ) { 220 abortf( "Signal on condition %p made with different monitor, expected %p got %i", this, this->monitors[i], this_thrd->current_monitors[i] ); 221 } // if 222 } 253 223 ); 254 224 255 monitor_desc * owner = this->monitors[0]; 256 lock( &owner->lock ); 257 { 258 thread_desc * unblock = pop_head( &this->blocked ); 259 push( &owner->signal_stack, unblock ); 260 } 261 unlock( &owner->lock ); 262 } 263 264 void signal( condition * this ) { 265 __signal_internal( this ); 266 } 225 lock_all( this->monitors, NULL, count ); 226 LIB_DEBUG_PRINT_SAFE("Signalling"); 227 228 __condition_node_t * node = pop_head( &this->blocked ); 229 for(int i = 0; i < count; i++) { 230 __condition_criterion_t * crit = &node->criteria[i]; 231 LIB_DEBUG_PRINT_SAFE(" %p", crit->target); 232 assert( !crit->ready ); 233 push( &crit->target->signal_stack, crit ); 234 } 235 236 LIB_DEBUG_PRINT_SAFE("\n"); 237 238 unlock_all( this->monitors, count ); 239 } 240 241 //----------------------------------------------------------------------------- 242 // Utilities 243 244 static inline void set_owner( monitor_desc * this, thread_desc * owner ) { 245 //Pass the monitor appropriately 246 this->owner = owner; 247 248 //We are passing the monitor to someone else, which means recursion level is not 0 249 this->recursion = owner ? 1 : 0; 250 } 251 252 static inline thread_desc * next_thread( monitor_desc * this ) { 253 //Check the signaller stack 254 __condition_criterion_t * urgent = pop( &this->signal_stack ); 255 if( urgent ) { 256 //The signaller stack is not empty, 257 //regardless of if we are ready to baton pass, 258 //we need to set the monitor as in use 259 set_owner( this, urgent->owner->waiting_thread ); 260 261 return check_condition( urgent ); 262 } 263 264 // No signaller thread 265 // Get the next thread in the entry_queue 266 thread_desc * new_owner = pop_head( &this->entry_queue ); 267 set_owner( this, new_owner ); 268 269 return new_owner; 270 } 271 272 static inline void lock_all( spinlock ** locks, unsigned short count ) { 273 for( int i = 0; i < count; i++ ) { 274 lock( locks[i] ); 275 } 276 } 277 278 static inline void lock_all( monitor_desc ** source, spinlock ** /*out*/ locks, unsigned short count ) { 279 for( int i = 0; i < count; i++ ) { 280 spinlock * l = &source[i]->lock; 281 lock( l ); 282 if(locks) locks[i] = l; 283 } 284 } 285 286 static inline void unlock_all( spinlock ** locks, unsigned short count ) { 287 for( int i = 0; i < count; i++ ) { 288 unlock( locks[i] ); 289 } 290 } 291 292 static inline void unlock_all( monitor_desc ** locks, unsigned short count ) { 293 for( int i = 0; i < count; i++ ) { 294 unlock( &locks[i]->lock ); 295 } 296 } 297 298 299 static inline void save_recursion ( monitor_desc ** ctx, unsigned int * /*out*/ recursions, unsigned short count ) { 300 for( int i = 0; i < count; i++ ) { 301 recursions[i] = ctx[i]->recursion; 302 } 303 } 304 305 static inline void restore_recursion( monitor_desc ** ctx, unsigned int * /*in */ recursions, unsigned short count ) { 306 for( int i = 0; i < count; i++ ) { 307 ctx[i]->recursion = recursions[i]; 308 } 309 } 310 311 // Function has 2 different behavior 312 // 1 - Marks a monitors as being ready to run 313 // 2 - Checks if all the monitors are ready to run 314 // if so return the thread to run 315 static inline thread_desc * check_condition( __condition_criterion_t * target ) { 316 __condition_node_t * node = target->owner; 317 unsigned short count = node->count; 318 __condition_criterion_t * criteria = node->criteria; 319 320 bool ready2run = true; 321 322 for( int i = 0; i < count; i++ ) { 323 LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target ); 324 if( &criteria[i] == target ) { 325 criteria[i].ready = true; 326 LIB_DEBUG_PRINT_SAFE( "True\n" ); 327 } 328 329 ready2run = criteria[i].ready && ready2run; 330 } 331 332 LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run ); 333 return ready2run ? node->waiting_thread : NULL; 334 } 335 336 static inline void brand_condition( condition * this ) { 337 thread_desc * thrd = this_thread(); 338 if( !this->monitors ) { 339 LIB_DEBUG_PRINT_SAFE("Branding\n"); 340 assertf( thrd->current_monitors != NULL, "No current monitor to brand condition", thrd->current_monitors ); 341 this->monitors = thrd->current_monitors; 342 this->monitor_count = thrd->current_monitor_count; 343 } 344 } 345 346 static inline unsigned short insert_unique( thread_desc ** thrds, unsigned short end, thread_desc * val ) { 347 for(int i = 0; i < end; i++) { 348 if( thrds[i] == val ) return end; 349 } 350 351 thrds[end] = val; 352 return end + 1; 353 } 354 355 void ?{}( __condition_blocked_queue_t * this ) { 356 this->head = NULL; 357 this->tail = &this->head; 358 } 359 360 void append( __condition_blocked_queue_t * this, __condition_node_t * c ) { 361 assert(this->tail != NULL); 362 *this->tail = c; 363 this->tail = &c->next; 364 } 365 366 __condition_node_t * pop_head( __condition_blocked_queue_t * this ) { 367 __condition_node_t * head = this->head; 368 if( head ) { 369 this->head = head->next; 370 if( !head->next ) { 371 this->tail = &this->head; 372 } 373 head->next = NULL; 374 } 375 return head; 376 } -
src/libcfa/interpose.c
r12d3187 r2055098 26 26 27 27 #include "libhdr/libdebug.h" 28 #include "libhdr/libtools.h" 28 29 #include "startup.h" 29 30 void abortf( const char *fmt, ... ) __attribute__ ((__nothrow__, __leaf__, __noreturn__));31 30 32 31 void interpose_startup(void) __attribute__(( constructor( STARTUP_PRIORITY_CORE ) )); … … 115 114 static char abort_text[ abort_text_size ]; 116 115 117 void abortf( const char fmt[], ... ) __attribute__ ((__nothrow__, __leaf__, __noreturn__)) { 118 void * kernel_data = kernel_abort(); 119 120 int len; 121 122 if( fmt ) { 123 va_list args; 124 va_start( args, fmt ); 116 extern "C" { 117 void abortf( const char fmt[], ... ) __attribute__ ((__nothrow__, __leaf__, __noreturn__)) { 118 void * kernel_data = kernel_abort(); 125 119 126 len = vsnprintf( abort_text, abort_text_size, fmt, args );120 int len; 127 121 128 va_end( args ); 122 if( fmt ) { 123 va_list args; 124 va_start( args, fmt ); 129 125 126 len = vsnprintf( abort_text, abort_text_size, fmt, args ); 127 128 va_end( args ); 129 130 __lib_debug_write( STDERR_FILENO, abort_text, len ); 131 __lib_debug_write( STDERR_FILENO, "\n", 1 ); 132 } 133 134 len = snprintf( abort_text, abort_text_size, "Cforall Runtime error (UNIX pid:%ld)\n", (long int)getpid() ); // use UNIX pid (versus getPid) 130 135 __lib_debug_write( STDERR_FILENO, abort_text, len ); 131 __lib_debug_write( STDERR_FILENO, "\n", 1 );132 }133 134 len = snprintf( abort_text, abort_text_size, "Cforall Runtime error (UNIX pid:%ld)\n", (long int)getpid() ); // use UNIX pid (versus getPid)135 __lib_debug_write( STDERR_FILENO, abort_text, len );136 136 137 137 138 kernel_abort_msg( kernel_data, abort_text, abort_text_size );138 kernel_abort_msg( kernel_data, abort_text, abort_text_size ); 139 139 140 libc_abort(); 140 libc_abort(); 141 } 141 142 } -
src/libcfa/libhdr/libtools.h
r12d3187 r2055098 22 22 // } // libAbort 23 23 24 #define abortf(...) abort(); 25 24 #ifdef __cforall 25 extern "C" { 26 #endif 27 void abortf( const char fmt[], ... ) __attribute__ ((__nothrow__, __leaf__, __noreturn__)); 28 #ifdef __cforall 29 } 30 #endif 26 31 27 32 #endif //__LIB_TOOLS_H__ -
src/libcfa/rational
r12d3187 r2055098 12 12 // Created On : Wed Apr 6 17:56:25 2016 13 13 // Last Modified By : Peter A. Buhr 14 // Last Modified On : Wed May 4 14:11:45 201615 // Update Count : 1614 // Last Modified On : Mon May 1 08:25:06 2017 15 // Update Count : 33 16 16 // 17 17 18 #ifndef RATIONAL_H 18 19 #define RATIONAL_H … … 21 22 22 23 // implementation 24 typedef long int RationalImpl; 23 25 struct Rational { 24 long intnumerator, denominator; // invariant: denominator > 026 RationalImpl numerator, denominator; // invariant: denominator > 0 25 27 }; // Rational 26 28 … … 31 33 // constructors 32 34 void ?{}( Rational * r ); 33 void ?{}( Rational * r, long intn );34 void ?{}( Rational * r, long int n, long intd );35 void ?{}( Rational * r, RationalImpl n ); 36 void ?{}( Rational * r, RationalImpl n, RationalImpl d ); 35 37 36 // getter/setter for numerator/denominator 37 long int numerator( Rational r ); 38 long int numerator( Rational r, long int n ); 39 long int denominator( Rational r ); 40 long int denominator( Rational r, long int d ); 38 // getter for numerator/denominator 39 RationalImpl numerator( Rational r ); 40 RationalImpl denominator( Rational r ); 41 [ RationalImpl, RationalImpl ] ?=?( * [ RationalImpl, RationalImpl ] dest, Rational src ); 42 // setter for numerator/denominator 43 RationalImpl numerator( Rational r, RationalImpl n ); 44 RationalImpl denominator( Rational r, RationalImpl d ); 41 45 42 46 // comparison … … 57 61 // conversion 58 62 double widen( Rational r ); 59 Rational narrow( double f, long intmd );63 Rational narrow( double f, RationalImpl md ); 60 64 61 65 // I/O -
src/libcfa/rational.c
r12d3187 r2055098 10 10 // Created On : Wed Apr 6 17:54:28 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 9 11:18:04 201613 // Update Count : 4012 // Last Modified On : Thu Apr 27 17:05:06 2017 13 // Update Count : 51 14 14 // 15 15 … … 30 30 // Calculate greatest common denominator of two numbers, the first of which may be negative. Used to reduce rationals. 31 31 // alternative: https://en.wikipedia.org/wiki/Binary_GCD_algorithm 32 static long int gcd( long int a, long intb ) {32 static RationalImpl gcd( RationalImpl a, RationalImpl b ) { 33 33 for ( ;; ) { // Euclid's algorithm 34 long intr = a % b;34 RationalImpl r = a % b; 35 35 if ( r == 0 ) break; 36 36 a = b; … … 40 40 } // gcd 41 41 42 static long int simplify( long int *n, long int*d ) {42 static RationalImpl simplify( RationalImpl *n, RationalImpl *d ) { 43 43 if ( *d == 0 ) { 44 44 serr | "Invalid rational number construction: denominator cannot be equal to 0." | endl; … … 56 56 } // rational 57 57 58 void ?{}( Rational * r, long intn ) {58 void ?{}( Rational * r, RationalImpl n ) { 59 59 r{ n, 1 }; 60 60 } // rational 61 61 62 void ?{}( Rational * r, long int n, long intd ) {63 long int t = simplify( &n, &d );// simplify62 void ?{}( Rational * r, RationalImpl n, RationalImpl d ) { 63 RationalImpl t = simplify( &n, &d ); // simplify 64 64 r->numerator = n / t; 65 65 r->denominator = d / t; … … 67 67 68 68 69 // getter /setterfor numerator/denominator70 71 long intnumerator( Rational r ) {69 // getter for numerator/denominator 70 71 RationalImpl numerator( Rational r ) { 72 72 return r.numerator; 73 73 } // numerator 74 74 75 long int numerator( Rational r, long int n ) { 76 long int prev = r.numerator; 77 long int t = gcd( abs( n ), r.denominator ); // simplify 75 RationalImpl denominator( Rational r ) { 76 return r.denominator; 77 } // denominator 78 79 [ RationalImpl, RationalImpl ] ?=?( * [ RationalImpl, RationalImpl ] dest, Rational src ) { 80 return *dest = src.[ numerator, denominator ]; 81 } 82 83 // setter for numerator/denominator 84 85 RationalImpl numerator( Rational r, RationalImpl n ) { 86 RationalImpl prev = r.numerator; 87 RationalImpl t = gcd( abs( n ), r.denominator ); // simplify 78 88 r.numerator = n / t; 79 89 r.denominator = r.denominator / t; … … 81 91 } // numerator 82 92 83 long int denominator( Rational r ) { 84 return r.denominator; 85 } // denominator 86 87 long int denominator( Rational r, long int d ) { 88 long int prev = r.denominator; 89 long int t = simplify( &r.numerator, &d ); // simplify 93 RationalImpl denominator( Rational r, RationalImpl d ) { 94 RationalImpl prev = r.denominator; 95 RationalImpl t = simplify( &r.numerator, &d ); // simplify 90 96 r.numerator = r.numerator / t; 91 97 r.denominator = d / t; … … 170 176 171 177 // http://www.ics.uci.edu/~eppstein/numth/frap.c 172 Rational narrow( double f, long intmd ) {178 Rational narrow( double f, RationalImpl md ) { 173 179 if ( md <= 1 ) { // maximum fractional digits too small? 174 180 return (Rational){ f, 1}; // truncate fraction … … 176 182 177 183 // continued fraction coefficients 178 long intm00 = 1, m11 = 1, m01 = 0, m10 = 0;179 long intai, t;184 RationalImpl m00 = 1, m11 = 1, m01 = 0, m10 = 0; 185 RationalImpl ai, t; 180 186 181 187 // find terms until denom gets too big 182 188 for ( ;; ) { 183 ai = ( long int)f;189 ai = (RationalImpl)f; 184 190 if ( ! (m10 * ai + m11 <= md) ) break; 185 191 t = m00 * ai + m01; … … 202 208 forall( dtype istype | istream( istype ) ) 203 209 istype * ?|?( istype *is, Rational *r ) { 204 long intt;210 RationalImpl t; 205 211 is | &(r->numerator) | &(r->denominator); 206 212 t = simplify( &(r->numerator), &(r->denominator) ); -
src/tests/.expect/32/attributes.txt
r12d3187 r2055098 1 attributes.c:74 error: cannot redefine typedef: ptrdiff_t 2 attributes.c:75 error: cannot redefine typedef: size_t 3 make: *** [attributes] Error 1 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size); 2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr); 3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void); 4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern int atexit(void (*__func)(void)); 5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(int __status); 6 extern int printf(const char *__restrict __format, ...); 7 int __la__Fi___1(){ 8 int ___retval_la__i_1; 9 L: __attribute__ ((unused)) ((void)1); 10 } 11 __attribute__ ((unused)) struct __anonymous0 { 12 }; 13 static inline void ___constructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1); 14 static inline void ___constructor__F_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1); 15 static inline void ___destructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1); 16 static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1); 17 static inline void ___constructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1){ 18 } 19 static inline void ___constructor__F_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1){ 20 } 21 static inline void ___destructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1){ 22 } 23 static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1){ 24 return ((struct __anonymous0 )___src__13s__anonymous0_1); 25 } 26 __attribute__ ((unused)) struct Agn1; 27 __attribute__ ((unused)) struct Agn2 { 28 }; 29 static inline void ___constructor__F_P5sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1); 30 static inline void ___constructor__F_P5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1, struct Agn2 ___src__5sAgn2_1); 31 static inline void ___destructor__F_P5sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1); 32 static inline struct Agn2 ___operator_assign__F5sAgn2_P5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1, struct Agn2 ___src__5sAgn2_1); 33 static inline void ___constructor__F_P5sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1){ 34 } 35 static inline void ___constructor__F_P5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1, struct Agn2 ___src__5sAgn2_1){ 36 } 37 static inline void ___destructor__F_P5sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1){ 38 } 39 static inline struct Agn2 ___operator_assign__F5sAgn2_P5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1, struct Agn2 ___src__5sAgn2_1){ 40 return ((struct Agn2 )___src__5sAgn2_1); 41 } 42 enum __attribute__ ((unused)) __anonymous1 { 43 __E1__C13e__anonymous1_1, 44 }; 45 enum __attribute__ ((unused)) Agn3; 46 enum __attribute__ ((packed)) Agn3 { 47 __E2__C5eAgn3_1, 48 }; 49 __attribute__ ((unused)) struct __anonymous2; 50 __attribute__ ((unused)) struct __anonymous3; 51 struct Fdl { 52 __attribute__ ((unused)) int __f1__i_1; 53 __attribute__ ((unused)) int __f2__i_1; 54 __attribute__ ((unused,unused)) int __f3__i_1; 55 __attribute__ ((unused)) int __f4__i_1; 56 __attribute__ ((unused,unused)) int __f5__i_1; 57 __attribute__ ((used,packed)) int __f6__i_1; 58 __attribute__ ((used,unused,unused)) int __f7__i_1; 59 __attribute__ ((used,used,unused)) int __f8__i_1; 60 __attribute__ ((unused)) int __anonymous_object0; 61 __attribute__ ((unused,unused)) int *__f9__Pi_1; 62 }; 63 static inline void ___constructor__F_P4sFdl_autogen___1(struct Fdl *___dst__P4sFdl_1); 64 static inline void ___constructor__F_P4sFdl4sFdl_autogen___1(struct Fdl *___dst__P4sFdl_1, struct Fdl ___src__4sFdl_1); 65 static inline void ___destructor__F_P4sFdl_autogen___1(struct Fdl *___dst__P4sFdl_1); 66 static inline struct Fdl ___operator_assign__F4sFdl_P4sFdl4sFdl_autogen___1(struct Fdl *___dst__P4sFdl_1, struct Fdl ___src__4sFdl_1); 67 static inline void ___constructor__F_P4sFdl_autogen___1(struct Fdl *___dst__P4sFdl_1){ 68 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))) /* ?{} */); 69 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))) /* ?{} */); 70 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))) /* ?{} */); 71 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))) /* ?{} */); 72 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))) /* ?{} */); 73 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))) /* ?{} */); 74 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))) /* ?{} */); 75 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))) /* ?{} */); 76 ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))) /* ?{} */); 77 } 78 static inline void ___constructor__F_P4sFdl4sFdl_autogen___1(struct Fdl *___dst__P4sFdl_1, struct Fdl ___src__4sFdl_1){ 79 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))=___src__4sFdl_1.__f1__i_1) /* ?{} */); 80 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))=___src__4sFdl_1.__f2__i_1) /* ?{} */); 81 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))=___src__4sFdl_1.__f3__i_1) /* ?{} */); 82 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))=___src__4sFdl_1.__f4__i_1) /* ?{} */); 83 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))=___src__4sFdl_1.__f5__i_1) /* ?{} */); 84 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))=___src__4sFdl_1.__f6__i_1) /* ?{} */); 85 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))=___src__4sFdl_1.__f7__i_1) /* ?{} */); 86 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))=___src__4sFdl_1.__f8__i_1) /* ?{} */); 87 ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))=___src__4sFdl_1.__f9__Pi_1) /* ?{} */); 88 } 89 static inline void ___destructor__F_P4sFdl_autogen___1(struct Fdl *___dst__P4sFdl_1){ 90 ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))) /* ^?{} */); 91 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))) /* ^?{} */); 92 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))) /* ^?{} */); 93 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))) /* ^?{} */); 94 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))) /* ^?{} */); 95 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))) /* ^?{} */); 96 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))) /* ^?{} */); 97 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))) /* ^?{} */); 98 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))) /* ^?{} */); 99 } 100 static inline struct Fdl ___operator_assign__F4sFdl_P4sFdl4sFdl_autogen___1(struct Fdl *___dst__P4sFdl_1, struct Fdl ___src__4sFdl_1){ 101 ((void)((*___dst__P4sFdl_1).__f1__i_1=___src__4sFdl_1.__f1__i_1)); 102 ((void)((*___dst__P4sFdl_1).__f2__i_1=___src__4sFdl_1.__f2__i_1)); 103 ((void)((*___dst__P4sFdl_1).__f3__i_1=___src__4sFdl_1.__f3__i_1)); 104 ((void)((*___dst__P4sFdl_1).__f4__i_1=___src__4sFdl_1.__f4__i_1)); 105 ((void)((*___dst__P4sFdl_1).__f5__i_1=___src__4sFdl_1.__f5__i_1)); 106 ((void)((*___dst__P4sFdl_1).__f6__i_1=___src__4sFdl_1.__f6__i_1)); 107 ((void)((*___dst__P4sFdl_1).__f7__i_1=___src__4sFdl_1.__f7__i_1)); 108 ((void)((*___dst__P4sFdl_1).__f8__i_1=___src__4sFdl_1.__f8__i_1)); 109 ((void)((*___dst__P4sFdl_1).__f9__Pi_1=___src__4sFdl_1.__f9__Pi_1)); 110 return ((struct Fdl )___src__4sFdl_1); 111 } 112 static inline void ___constructor__F_P4sFdli_autogen___1(struct Fdl *___dst__P4sFdl_1, int __f1__i_1){ 113 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))=__f1__i_1) /* ?{} */); 114 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))) /* ?{} */); 115 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))) /* ?{} */); 116 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))) /* ?{} */); 117 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))) /* ?{} */); 118 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))) /* ?{} */); 119 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))) /* ?{} */); 120 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))) /* ?{} */); 121 ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))) /* ?{} */); 122 } 123 static inline void ___constructor__F_P4sFdlii_autogen___1(struct Fdl *___dst__P4sFdl_1, int __f1__i_1, int __f2__i_1){ 124 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))=__f1__i_1) /* ?{} */); 125 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))=__f2__i_1) /* ?{} */); 126 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))) /* ?{} */); 127 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))) /* ?{} */); 128 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))) /* ?{} */); 129 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))) /* ?{} */); 130 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))) /* ?{} */); 131 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))) /* ?{} */); 132 ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))) /* ?{} */); 133 } 134 static inline void ___constructor__F_P4sFdliii_autogen___1(struct Fdl *___dst__P4sFdl_1, int __f1__i_1, int __f2__i_1, int __f3__i_1){ 135 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))=__f1__i_1) /* ?{} */); 136 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))=__f2__i_1) /* ?{} */); 137 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))=__f3__i_1) /* ?{} */); 138 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))) /* ?{} */); 139 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))) /* ?{} */); 140 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))) /* ?{} */); 141 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))) /* ?{} */); 142 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))) /* ?{} */); 143 ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))) /* ?{} */); 144 } 145 static inline void ___constructor__F_P4sFdliiii_autogen___1(struct Fdl *___dst__P4sFdl_1, int __f1__i_1, int __f2__i_1, int __f3__i_1, int __f4__i_1){ 146 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))=__f1__i_1) /* ?{} */); 147 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))=__f2__i_1) /* ?{} */); 148 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))=__f3__i_1) /* ?{} */); 149 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))=__f4__i_1) /* ?{} */); 150 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))) /* ?{} */); 151 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))) /* ?{} */); 152 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))) /* ?{} */); 153 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))) /* ?{} */); 154 ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))) /* ?{} */); 155 } 156 static inline void ___constructor__F_P4sFdliiiii_autogen___1(struct Fdl *___dst__P4sFdl_1, int __f1__i_1, int __f2__i_1, int __f3__i_1, int __f4__i_1, int __f5__i_1){ 157 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))=__f1__i_1) /* ?{} */); 158 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))=__f2__i_1) /* ?{} */); 159 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))=__f3__i_1) /* ?{} */); 160 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))=__f4__i_1) /* ?{} */); 161 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))=__f5__i_1) /* ?{} */); 162 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))) /* ?{} */); 163 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))) /* ?{} */); 164 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))) /* ?{} */); 165 ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))) /* ?{} */); 166 } 167 static inline void ___constructor__F_P4sFdliiiiii_autogen___1(struct Fdl *___dst__P4sFdl_1, int __f1__i_1, int __f2__i_1, int __f3__i_1, int __f4__i_1, int __f5__i_1, int __f6__i_1){ 168 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))=__f1__i_1) /* ?{} */); 169 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))=__f2__i_1) /* ?{} */); 170 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))=__f3__i_1) /* ?{} */); 171 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))=__f4__i_1) /* ?{} */); 172 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))=__f5__i_1) /* ?{} */); 173 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))=__f6__i_1) /* ?{} */); 174 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))) /* ?{} */); 175 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))) /* ?{} */); 176 ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))) /* ?{} */); 177 } 178 static inline void ___constructor__F_P4sFdliiiiiii_autogen___1(struct Fdl *___dst__P4sFdl_1, int __f1__i_1, int __f2__i_1, int __f3__i_1, int __f4__i_1, int __f5__i_1, int __f6__i_1, int __f7__i_1){ 179 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))=__f1__i_1) /* ?{} */); 180 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))=__f2__i_1) /* ?{} */); 181 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))=__f3__i_1) /* ?{} */); 182 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))=__f4__i_1) /* ?{} */); 183 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))=__f5__i_1) /* ?{} */); 184 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))=__f6__i_1) /* ?{} */); 185 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))=__f7__i_1) /* ?{} */); 186 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))) /* ?{} */); 187 ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))) /* ?{} */); 188 } 189 static inline void ___constructor__F_P4sFdliiiiiiii_autogen___1(struct Fdl *___dst__P4sFdl_1, int __f1__i_1, int __f2__i_1, int __f3__i_1, int __f4__i_1, int __f5__i_1, int __f6__i_1, int __f7__i_1, int __f8__i_1){ 190 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))=__f1__i_1) /* ?{} */); 191 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))=__f2__i_1) /* ?{} */); 192 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))=__f3__i_1) /* ?{} */); 193 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))=__f4__i_1) /* ?{} */); 194 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))=__f5__i_1) /* ?{} */); 195 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))=__f6__i_1) /* ?{} */); 196 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))=__f7__i_1) /* ?{} */); 197 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))=__f8__i_1) /* ?{} */); 198 ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))) /* ?{} */); 199 } 200 static inline void ___constructor__F_P4sFdliiiiiiiiPi_autogen___1(struct Fdl *___dst__P4sFdl_1, int __f1__i_1, int __f2__i_1, int __f3__i_1, int __f4__i_1, int __f5__i_1, int __f6__i_1, int __f7__i_1, int __f8__i_1, int *__f9__Pi_1){ 201 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))=__f1__i_1) /* ?{} */); 202 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))=__f2__i_1) /* ?{} */); 203 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))=__f3__i_1) /* ?{} */); 204 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))=__f4__i_1) /* ?{} */); 205 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))=__f5__i_1) /* ?{} */); 206 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))=__f6__i_1) /* ?{} */); 207 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))=__f7__i_1) /* ?{} */); 208 ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))=__f8__i_1) /* ?{} */); 209 ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))=__f9__Pi_1) /* ?{} */); 210 } 211 __attribute__ ((unused)) int __f__Fi___1() asm ( "xyz" ); 212 __attribute__ ((used,used)) const int __vd1__Ci_1; 213 __attribute__ ((used,unused)) const int __vd2__Ci_1; 214 __attribute__ ((used,used,used,used)) const int *__vd3__PCi_1; 215 __attribute__ ((used,used,unused,used,unused)) const int *__vd4__PCi_1; 216 __attribute__ ((used,used,used)) const int __vd5__A0Ci_1[((unsigned int )5)]; 217 __attribute__ ((used,used,unused,used)) const int __vd6__A0Ci_1[((unsigned int )5)]; 218 __attribute__ ((used,used,used,used)) const int (*__vd7__PFCi___1)(); 219 __attribute__ ((used,used,unused,used,used)) const int (*__vd8__PFCi___1)(); 220 __attribute__ ((unused,used)) int __f1__Fi___1(); 221 __attribute__ ((unused)) int __f1__Fi___1(){ 222 int ___retval_f1__i_1; 223 } 224 __attribute__ ((unused,unused,unused,used)) int **const __f2__FCPPi___1(); 225 __attribute__ ((unused,unused,unused)) int **const __f2__FCPPi___1(){ 226 int **const ___retval_f2__CPPi_1; 227 } 228 __attribute__ ((unused,used,unused)) int (*__f3__FPA0i_i__1(int __anonymous_object1))[]; 229 __attribute__ ((unused,unused)) int (*__f3__FPA0i_i__1(int __p__i_1))[]{ 230 int (*___retval_f3__PA0i_1)[]; 231 } 232 __attribute__ ((unused,used,unused)) int (*__f4__FPFi_i____1())(int __anonymous_object2); 233 __attribute__ ((unused,unused)) int (*__f4__FPFi_i____1())(int __anonymous_object3){ 234 int (*___retval_f4__PFi_i__1)(int __anonymous_object4); 235 } 236 int __vtr__Fi___1(){ 237 int ___retval_vtr__i_1; 238 __attribute__ ((unused,unused,used)) int __t1__i_2; 239 __attribute__ ((unused,unused,unused,unused,unused)) int **__t2__PPi_2; 240 __attribute__ ((unused,unused,unused)) int __t3__A0i_2[((unsigned int )5)]; 241 __attribute__ ((unused,unused,unused,unused,unused)) int **__t4__A0PPi_2[((unsigned int )5)]; 242 __attribute__ ((unused,unused,unused)) int __t5__Fi___2(); 243 __attribute__ ((unused,unused,unused,unused)) int *__t6__FPi___2(); 244 } 245 int __ipd1__Fi_ii__1(__attribute__ ((unused,unused,unused)) int __p__i_1, __attribute__ ((unused,unused,unused)) int __q__i_1); 246 int __ipd1__Fi_ii__1(__attribute__ ((unused,unused,unused)) int __p__i_1, __attribute__ ((unused,unused,unused)) int __q__i_1){ 247 int ___retval_ipd1__i_1; 248 } 249 int __ipd2__Fi_PiPi__1(__attribute__ ((unused,unused,unused,unused)) int *__p__Pi_1, __attribute__ ((unused,unused,unused)) int *__q__Pi_1); 250 int __ipd2__Fi_PiPi__1(__attribute__ ((unused,unused,unused,unused)) int *__p__Pi_1, __attribute__ ((unused,unused,unused)) int *__q__Pi_1){ 251 int ___retval_ipd2__i_1; 252 } 253 int __ipd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__p__Pi_1, __attribute__ ((unused,unused,unused)) int *__q__Pi_1); 254 int __ipd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__p__Pi_1, __attribute__ ((unused,unused,unused)) int *__q__Pi_1){ 255 int ___retval_ipd3__i_1; 256 } 257 int __ipd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__p__PFi___1)(), __attribute__ ((unused,unused,unused)) int (*__q__PFi___1)()); 258 int __ipd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__p__PFi___1)(), __attribute__ ((unused,unused,unused)) int (*__q__PFi___1)()){ 259 int ___retval_ipd4__i_1; 260 } 261 int __tpr1__Fi_i__1(__attribute__ ((unused,unused,unused)) int __Foo__i_1); 262 int __tpr2__Fi_PPi__1(__attribute__ ((unused,unused,unused,unused,unused,unused)) int **__Foo__PPi_1); 263 int __tpr3__Fi_Pi__1(__attribute__ ((unused,unused,unused)) int *__Foo__Pi_1); 264 int __tpr4__Fi_PFi_Pi___1(__attribute__ ((unused,unused)) int (*__anonymous_object5)(__attribute__ ((unused,unused)) int __anonymous_object6[((unsigned int )5)])); 265 int __tpr5__Fi_PFi____1(__attribute__ ((unused,unused,unused)) int (*__Foo__PFi___1)()); 266 int __tpr6__Fi_PFi____1(__attribute__ ((unused,unused,unused)) int (*__Foo__PFi___1)()); 267 int __tpr7__Fi_PFi_PFi_i____1(__attribute__ ((unused,unused)) int (*__anonymous_object7)(__attribute__ ((unused)) int (*__anonymous_object8)(__attribute__ ((unused,unused)) int __anonymous_object9))); 268 int __ad__Fi___1(){ 269 int ___retval_ad__i_1; 270 __attribute__ ((used,unused)) int __ad1__i_2; 271 __attribute__ ((unused,unused,unused)) int *__ad2__Pi_2; 272 __attribute__ ((unused,unused,unused)) int __ad3__A0i_2[((unsigned int )5)]; 273 __attribute__ ((unused,unused,unused,unused,unused)) int (*__ad4__PA0i_2)[((unsigned int )10)]; 274 __attribute__ ((unused,unused,unused,unused,used)) int __ad5__i_2; 275 __attribute__ ((unused,unused,unused,unused,unused)) int __ad6__Fi___2(); 276 ((void)sizeof(__attribute__ ((unused,unused)) int )); 277 ((void)sizeof(__attribute__ ((unused,unused,unused,unused)) int **)); 278 ((void)sizeof(__attribute__ ((unused,unused,unused)) int [5])); 279 ((void)sizeof(__attribute__ ((unused,unused,unused)) int (*)[10])); 280 ((void)sizeof(__attribute__ ((unused,unused,unused)) int ())); 281 __attribute__ ((unused)) struct __anonymous4 { 282 int __i__i_2; 283 }; 284 inline void ___constructor__F_P13s__anonymous4_autogen___2(struct __anonymous4 *___dst__P13s__anonymous4_2){ 285 ((void)((*((int *)(&(*___dst__P13s__anonymous4_2).__i__i_2)))) /* ?{} */); 286 } 287 inline void ___constructor__F_P13s__anonymous413s__anonymous4_autogen___2(struct __anonymous4 *___dst__P13s__anonymous4_2, struct __anonymous4 ___src__13s__anonymous4_2){ 288 ((void)((*((int *)(&(*___dst__P13s__anonymous4_2).__i__i_2)))=___src__13s__anonymous4_2.__i__i_2) /* ?{} */); 289 } 290 inline void ___destructor__F_P13s__anonymous4_autogen___2(struct __anonymous4 *___dst__P13s__anonymous4_2){ 291 ((void)((*((int *)(&(*___dst__P13s__anonymous4_2).__i__i_2)))) /* ^?{} */); 292 } 293 inline struct __anonymous4 ___operator_assign__F13s__anonymous4_P13s__anonymous413s__anonymous4_autogen___2(struct __anonymous4 *___dst__P13s__anonymous4_2, struct __anonymous4 ___src__13s__anonymous4_2){ 294 ((void)((*___dst__P13s__anonymous4_2).__i__i_2=___src__13s__anonymous4_2.__i__i_2)); 295 return ((struct __anonymous4 )___src__13s__anonymous4_2); 296 } 297 inline void ___constructor__F_P13s__anonymous4i_autogen___2(struct __anonymous4 *___dst__P13s__anonymous4_2, int __i__i_2){ 298 ((void)((*((int *)(&(*___dst__P13s__anonymous4_2).__i__i_2)))=__i__i_2) /* ?{} */); 299 } 300 ((void)sizeof(struct __anonymous4 )); 301 enum __attribute__ ((unused)) __anonymous5 { 302 __R__C13e__anonymous5_2, 303 }; 304 inline void ___constructor__F_P13e__anonymous5_intrinsic___2(enum __anonymous5 *___dst__P13e__anonymous5_2){ 305 } 306 inline void ___constructor__F_P13e__anonymous513e__anonymous5_intrinsic___2(enum __anonymous5 *___dst__P13e__anonymous5_2, enum __anonymous5 ___src__13e__anonymous5_2){ 307 ((void)((*___dst__P13e__anonymous5_2)=___src__13e__anonymous5_2)); 308 } 309 inline void ___destructor__F_P13e__anonymous5_intrinsic___2(enum __anonymous5 *___dst__P13e__anonymous5_2){ 310 } 311 inline enum __anonymous5 ___operator_assign__F13e__anonymous5_P13e__anonymous513e__anonymous5_intrinsic___2(enum __anonymous5 *___dst__P13e__anonymous5_2, enum __anonymous5 ___src__13e__anonymous5_2){ 312 return ((enum __anonymous5 )((*___dst__P13e__anonymous5_2)=___src__13e__anonymous5_2)); 313 } 314 ((void)sizeof(enum __anonymous5 )); 315 } 316 int __apd1__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__anonymous_object10, __attribute__ ((unused,unused,unused)) int *__anonymous_object11); 317 int __apd2__Fi_PPiPPi__1(__attribute__ ((unused,unused,unused,unused)) int **__anonymous_object12, __attribute__ ((unused,unused,unused,unused)) int **__anonymous_object13); 318 int __apd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__anonymous_object14, __attribute__ ((unused,unused,unused)) int *__anonymous_object15); 319 int __apd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object16)(), __attribute__ ((unused,unused,unused)) int (*__anonymous_object17)()); 320 int __apd5__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object18)(__attribute__ ((unused)) int __anonymous_object19), __attribute__ ((unused,unused,unused)) int (*__anonymous_object20)(__attribute__ ((unused)) int __anonymous_object21)); 321 int __apd6__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object22)(), __attribute__ ((unused,unused,unused)) int (*__anonymous_object23)()); 322 int __apd7__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object24)(__attribute__ ((unused)) int __anonymous_object25), __attribute__ ((unused,unused,unused)) int (*__anonymous_object26)(__attribute__ ((unused)) int __anonymous_object27)); 323 struct Vad { 324 __attribute__ ((unused)) int __anonymous_object28; 325 __attribute__ ((unused,unused)) int *__anonymous_object29; 326 __attribute__ ((unused,unused)) int __anonymous_object30[((unsigned int )10)]; 327 __attribute__ ((unused,unused)) int (*__anonymous_object31)(); 328 }; 329 static inline void ___constructor__F_P4sVad_autogen___1(struct Vad *___dst__P4sVad_1); 330 static inline void ___constructor__F_P4sVad4sVad_autogen___1(struct Vad *___dst__P4sVad_1, struct Vad ___src__4sVad_1); 331 static inline void ___destructor__F_P4sVad_autogen___1(struct Vad *___dst__P4sVad_1); 332 static inline struct Vad ___operator_assign__F4sVad_P4sVad4sVad_autogen___1(struct Vad *___dst__P4sVad_1, struct Vad ___src__4sVad_1); 333 static inline void ___constructor__F_P4sVad_autogen___1(struct Vad *___dst__P4sVad_1){ 334 } 335 static inline void ___constructor__F_P4sVad4sVad_autogen___1(struct Vad *___dst__P4sVad_1, struct Vad ___src__4sVad_1){ 336 } 337 static inline void ___destructor__F_P4sVad_autogen___1(struct Vad *___dst__P4sVad_1){ 338 } 339 static inline struct Vad ___operator_assign__F4sVad_P4sVad4sVad_autogen___1(struct Vad *___dst__P4sVad_1, struct Vad ___src__4sVad_1){ 340 return ((struct Vad )___src__4sVad_1); 341 } -
src/tests/.expect/64/attributes.txt
r12d3187 r2055098 9 9 L: __attribute__ ((unused)) ((void)1); 10 10 } 11 struct __attribute__ ((unused))__anonymous0 {11 __attribute__ ((unused)) struct __anonymous0 { 12 12 }; 13 13 static inline void ___constructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1); … … 24 24 return ((struct __anonymous0 )___src__13s__anonymous0_1); 25 25 } 26 struct __attribute__ ((unused))Agn1;27 struct __attribute__ ((unused))Agn2 {26 __attribute__ ((unused)) struct Agn1; 27 __attribute__ ((unused)) struct Agn2 { 28 28 }; 29 29 static inline void ___constructor__F_P5sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1); … … 47 47 __E2__C5eAgn3_1, 48 48 }; 49 struct __attribute__ ((unused))__anonymous2;50 struct __attribute__ ((unused))__anonymous3;49 __attribute__ ((unused)) struct __anonymous2; 50 __attribute__ ((unused)) struct __anonymous3; 51 51 struct Fdl { 52 52 __attribute__ ((unused)) int __f1__i_1; … … 234 234 int (*___retval_f4__PFi_i__1)(int __anonymous_object4); 235 235 } 236 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(long unsigned int __size);237 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);238 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);239 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern int atexit0(void (*__func)(void), void *__anonymous_object5, void *__anonymous_object6);240 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(int __status);241 __attribute__ ((format(printf, 1, 2))) extern int printf(const char *__restrict __format, ...);242 236 int __vtr__Fi___1(){ 243 237 int ___retval_vtr__i_1; … … 268 262 int __tpr2__Fi_PPi__1(__attribute__ ((unused,unused,unused,unused,unused,unused)) int **__Foo__PPi_1); 269 263 int __tpr3__Fi_Pi__1(__attribute__ ((unused,unused,unused)) int *__Foo__Pi_1); 270 int __tpr4__Fi_PFi_Pi___1(__attribute__ ((unused,unused)) int (*__anonymous_object 7)(__attribute__ ((unused,unused)) int __anonymous_object8[((long unsigned int )5)]));264 int __tpr4__Fi_PFi_Pi___1(__attribute__ ((unused,unused)) int (*__anonymous_object5)(__attribute__ ((unused,unused)) int __anonymous_object6[((long unsigned int )5)])); 271 265 int __tpr5__Fi_PFi____1(__attribute__ ((unused,unused,unused)) int (*__Foo__PFi___1)()); 272 266 int __tpr6__Fi_PFi____1(__attribute__ ((unused,unused,unused)) int (*__Foo__PFi___1)()); 273 int __tpr7__Fi_PFi_PFi_i____1(__attribute__ ((unused,unused)) int (*__anonymous_object 9)(__attribute__ ((unused)) int (*__anonymous_object10)(__attribute__ ((unused,unused)) int __anonymous_object11)));267 int __tpr7__Fi_PFi_PFi_i____1(__attribute__ ((unused,unused)) int (*__anonymous_object7)(__attribute__ ((unused)) int (*__anonymous_object8)(__attribute__ ((unused,unused)) int __anonymous_object9))); 274 268 int __ad__Fi___1(){ 275 269 int ___retval_ad__i_1; … … 285 279 ((void)sizeof(__attribute__ ((unused,unused,unused)) int (*)[10])); 286 280 ((void)sizeof(__attribute__ ((unused,unused,unused)) int ())); 287 struct __attribute__ ((unused))__anonymous4 {281 __attribute__ ((unused)) struct __anonymous4 { 288 282 int __i__i_2; 289 283 }; … … 320 314 ((void)sizeof(enum __anonymous5 )); 321 315 } 322 int __apd1__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__anonymous_object1 2, __attribute__ ((unused,unused,unused)) int *__anonymous_object13);323 int __apd2__Fi_PPiPPi__1(__attribute__ ((unused,unused,unused,unused)) int **__anonymous_object1 4, __attribute__ ((unused,unused,unused,unused)) int **__anonymous_object15);324 int __apd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__anonymous_object1 6, __attribute__ ((unused,unused,unused)) int *__anonymous_object17);325 int __apd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object1 8)(), __attribute__ ((unused,unused,unused)) int (*__anonymous_object19)());326 int __apd5__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object 20)(__attribute__ ((unused)) int __anonymous_object21), __attribute__ ((unused,unused,unused)) int (*__anonymous_object22)(__attribute__ ((unused)) int __anonymous_object23));327 int __apd6__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object2 4)(), __attribute__ ((unused,unused,unused)) int (*__anonymous_object25)());328 int __apd7__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object2 6)(__attribute__ ((unused)) int __anonymous_object27), __attribute__ ((unused,unused,unused)) int (*__anonymous_object28)(__attribute__ ((unused)) int __anonymous_object29));316 int __apd1__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__anonymous_object10, __attribute__ ((unused,unused,unused)) int *__anonymous_object11); 317 int __apd2__Fi_PPiPPi__1(__attribute__ ((unused,unused,unused,unused)) int **__anonymous_object12, __attribute__ ((unused,unused,unused,unused)) int **__anonymous_object13); 318 int __apd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__anonymous_object14, __attribute__ ((unused,unused,unused)) int *__anonymous_object15); 319 int __apd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object16)(), __attribute__ ((unused,unused,unused)) int (*__anonymous_object17)()); 320 int __apd5__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object18)(__attribute__ ((unused)) int __anonymous_object19), __attribute__ ((unused,unused,unused)) int (*__anonymous_object20)(__attribute__ ((unused)) int __anonymous_object21)); 321 int __apd6__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object22)(), __attribute__ ((unused,unused,unused)) int (*__anonymous_object23)()); 322 int __apd7__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object24)(__attribute__ ((unused)) int __anonymous_object25), __attribute__ ((unused,unused,unused)) int (*__anonymous_object26)(__attribute__ ((unused)) int __anonymous_object27)); 329 323 struct Vad { 330 __attribute__ ((unused)) int __anonymous_object 30;331 __attribute__ ((unused,unused)) int *__anonymous_object 31;332 __attribute__ ((unused,unused)) int __anonymous_object3 2[((long unsigned int )10)];333 __attribute__ ((unused,unused)) int (*__anonymous_object3 3)();324 __attribute__ ((unused)) int __anonymous_object28; 325 __attribute__ ((unused,unused)) int *__anonymous_object29; 326 __attribute__ ((unused,unused)) int __anonymous_object30[((long unsigned int )10)]; 327 __attribute__ ((unused,unused)) int (*__anonymous_object31)(); 334 328 }; 335 329 static inline void ___constructor__F_P4sVad_autogen___1(struct Vad *___dst__P4sVad_1); -
src/tests/.expect/castError.txt
r12d3187 r2055098 39 39 40 40 41 make: *** [castError] Error 1 -
src/tests/.expect/completeTypeError.txt
r12d3187 r2055098 41 41 42 42 43 make: *** [completeTypeError] Error 1 -
src/tests/.expect/constant0-1DP.txt
r12d3187 r2055098 31 31 constant0-1.c:50 error: duplicate object definition for x: const pointer to pointer to signed int 32 32 constant0-1.c:50 error: duplicate object definition for 0: pointer to pointer to signed int 33 make: *** [constant0-1DP] Error 1 -
src/tests/.expect/constant0-1NDDP.txt
r12d3187 r2055098 15 15 constant0-1.c:67 error: duplicate object definition for x: const pointer to signed int 16 16 constant0-1.c:67 error: duplicate object definition for 0: const pointer to signed int 17 make: *** [constant0-1NDDP] Error 1 -
src/tests/.expect/declarationErrors.txt
r12d3187 r2055098 67 67 68 68 69 make: *** [declarationErrors] Error 1 -
src/tests/.expect/dtor-early-exit-ERR1.txt
r12d3187 r2055098 1 1 dtor-early-exit.c:142 error: jump to label 'L1' crosses initialization of y Branch (Goto) 2 3 make: *** [dtor-early-exit-ERR1] Error 1 -
src/tests/.expect/dtor-early-exit-ERR2.txt
r12d3187 r2055098 1 1 dtor-early-exit.c:142 error: jump to label 'L2' crosses initialization of y Branch (Goto) 2 3 make: *** [dtor-early-exit-ERR2] Error 1 -
src/tests/.expect/memberCtors-ERR1.txt
r12d3187 r2055098 1 1 memberCtors.c:62 error: in void ?{}(B *b), field a2 used before being constructed 2 make: *** [memberCtors-ERR1] Error 1 -
src/tests/.expect/scopeErrors.txt
r12d3187 r2055098 7 7 with body 8 8 CompoundStmt 9 10 make: *** [scopeErrors] Error 1 -
src/tests/.gitignore
r12d3187 r2055098 1 1 .out/ 2 .err/ -
src/tests/Makefile.am
r12d3187 r2055098 22 22 concurrent=yes 23 23 quick_test+= coroutine thread monitor 24 concurrent_test=coroutine thread monitor multi-monitor sched-int sched-int-multi sched-int-multi2 sched-ext sched-ext-multi preempt 24 25 else 25 26 concurrent=no 27 concurrent_test= 26 28 endif 27 28 29 29 30 # applies to both programs 30 31 EXTRA_FLAGS = 31 CFLAGS = -g -Wall -Wno-unused-function @CFA_FLAGS@ ${EXTRA_FLAGS} 32 BUILD_FLAGS = -g -Wall -Wno-unused-function @CFA_FLAGS@ ${EXTRA_FLAGS} 33 TEST_FLAGS = $(if $(test), 2> .err/${@}.log, ) 34 CFLAGS = ${TEST_FLAGS} ${BUILD_FLAGS} 32 35 CC = @CFA_BINDIR@/@CFA_NAME@ 33 36 … … 51 54 @+python test.py --list --concurrent=${concurrent} 52 55 56 concurrency : 57 @+python test.py --debug=${debug} --concurrent=${concurrent} ${concurrent_test} 58 53 59 .dummy : .dummy.c 54 ${CC} ${ CFLAGS} -XCFA -n ${<} -o ${@}60 ${CC} ${BUILD_FLAGS} -XCFA -n ${<} -o ${@} #don't use CFLAGS, this rule is not a real test 55 61 56 62 constant0-1DP : constant0-1.c -
src/tests/Makefile.in
r12d3187 r2055098 125 125 CFA_NAME = @CFA_NAME@ 126 126 CFA_PREFIX = @CFA_PREFIX@ 127 CFLAGS = -g -Wall -Wno-unused-function @CFA_FLAGS@ ${EXTRA_FLAGS}127 CFLAGS = ${TEST_FLAGS} ${BUILD_FLAGS} 128 128 CPP = @CPP@ 129 129 CPPFLAGS = @CPPFLAGS@ … … 229 229 @BUILD_CONCURRENCY_FALSE@concurrent = no 230 230 @BUILD_CONCURRENCY_TRUE@concurrent = yes 231 @BUILD_CONCURRENCY_FALSE@concurrent_test = 232 @BUILD_CONCURRENCY_TRUE@concurrent_test = coroutine thread monitor multi-monitor sched-int sched-int-multi sched-int-multi2 sched-ext sched-ext-multi preempt 231 233 232 234 # applies to both programs 233 235 EXTRA_FLAGS = 236 BUILD_FLAGS = -g -Wall -Wno-unused-function @CFA_FLAGS@ ${EXTRA_FLAGS} 237 TEST_FLAGS = $(if $(test), 2> .err/${@}.log, ) 234 238 fstream_test_SOURCES = fstream_test.c 235 239 vector_test_SOURCES = vector/vector_int.c vector/array.c vector/vector_test.c … … 669 673 @+python test.py --list --concurrent=${concurrent} 670 674 675 concurrency : 676 @+python test.py --debug=${debug} --concurrent=${concurrent} ${concurrent_test} 677 671 678 .dummy : .dummy.c 672 ${CC} ${ CFLAGS} -XCFA -n ${<} -o ${@}679 ${CC} ${BUILD_FLAGS} -XCFA -n ${<} -o ${@} #don't use CFLAGS, this rule is not a real test 673 680 674 681 constant0-1DP : constant0-1.c -
src/tests/attributes.c
r12d3187 r2055098 68 68 __attribute__(( unused )) int (* __attribute__(( unused )) f4())(int) __attribute__(( used )); 69 69 __attribute__(( unused )) int (* __attribute__(( unused )) f4())(int) {} 70 71 #ifdef __CFA__72 extern "C" {73 #endif // __CFA__74 typedef long int ptrdiff_t;75 typedef long unsigned int size_t;76 extern void *malloc (size_t __size) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__malloc__)) ;77 extern void free (void *__ptr) __attribute__ ((__nothrow__ , __leaf__));78 extern void abort (void) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__noreturn__));79 extern int atexit0 (void (*__func) (void), void *, void *) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));80 extern void exit (int __status) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__noreturn__));81 extern int printf (__const char *__restrict __format, ...) __attribute__ ((format (printf, 1, 2)));82 #ifdef __CFA__83 }84 #endif // __CFA__85 70 86 71 -
src/tests/rational.c
r12d3187 r2055098 10 10 // Created On : Mon Mar 28 08:43:12 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T ue Jul 5 18:29:37 201613 // Update Count : 2512 // Last Modified On : Thu Apr 27 17:05:19 2017 13 // Update Count : 40 14 14 // 15 15 … … 36 36 b = (Rational){ -3, 2 }; 37 37 sout | a | b | endl; 38 sout | a == 1 | endl; 38 // sout | a == 1 | endl; // FIX ME 39 39 sout | a != b | endl; 40 40 sout | a < b | endl; … … 61 61 sout | narrow( 3.14159265358979, 256 ) | endl; 62 62 63 sout | "decompose" | endl; 64 RationalImpl n, d; 65 [n, d] = a; 66 sout | a | n | d | endl; 67 68 sout | "more tests" | endl; 63 69 Rational x = { 1, 2 }, y = { 2 }; 64 70 sout | x - y | endl; -
src/tests/sched-int.c
r12d3187 r2055098 1 #include <fstream> 1 2 #include <kernel> 2 3 #include <monitor> … … 15 16 16 17 void step1( global_t * mutex this ) { 18 sout | "Step 1" | endl; 17 19 this->value = 1; 18 20 wait( &cond ); … … 22 24 if( this->value != 1) abort(); 23 25 26 sout | "Step 2" | endl; 24 27 this->value = 2; 25 28 signal( &cond ); … … 29 32 if( this->value != 2) abort(); 30 33 31 this->value = 2; 34 sout | "Step 3" | endl; 35 this->value = 3; 32 36 signal( &cond ); 33 37 } -
src/tests/test.py
r12d3187 r2055098 6 6 from os import listdir, environ 7 7 from os.path import isfile, join, splitext 8 from subprocess import Popen, PIPE, STDOUT8 from pybin.tools import * 9 9 10 10 import argparse 11 import multiprocessing 11 12 import os 12 13 import re 13 import s tat14 import signal 14 15 import sys 15 16 … … 26 27 def getMachineType(): 27 28 sh('echo "void ?{}(int*a,int b){}int main(){return 0;}" > .dummy.c') 28 sh("make .dummy", print2stdout=False) 29 ret, out = sh("make .dummy -s", print2stdout=True) 30 31 if ret != 0: 32 print("Failed to identify architecture:") 33 print(out) 34 print("Stopping") 35 rm( (".dummy.c",".dummy") ) 36 sys.exit(1) 37 29 38 _, out = sh("file .dummy", print2stdout=False) 30 sh("rm -f .dummy.c > /dev/null 2>&1")31 sh("rm -f .dummy > /dev/null 2>&1") 39 rm( (".dummy.c",".dummy") ) 40 32 41 return re.search("ELF\s([0-9]+)-bit", out).group(1) 33 42 … … 58 67 return generic_list + typed_list + concurrent_list; 59 68 60 # helper functions to run terminal commands 61 def sh(cmd, dry_run = False, print2stdout = True): 62 if dry_run : # if this is a dry_run, only print the commands that would be ran 63 print("cmd: %s" % cmd) 64 return 0, None 65 else : # otherwise create a pipe and run the desired command 66 proc = Popen(cmd, stdout=None if print2stdout else PIPE, stderr=STDOUT, shell=True) 67 out, err = proc.communicate() 68 return proc.returncode, out 69 70 # helper function to replace patterns in a file 71 def file_replace(fname, pat, s_after): 72 # first, see if the pattern is even in the file. 73 with open(fname) as f: 74 if not any(re.search(pat, line) for line in f): 75 return # pattern does not occur in file so we are done. 76 77 # pattern is in the file, so perform replace operation. 78 with open(fname) as f: 79 out_fname = fname + ".tmp" 80 out = open(out_fname, "w") 81 for line in f: 82 out.write(re.sub(pat, s_after, line)) 83 out.close() 84 os.rename(out_fname, fname) 85 86 # tests output may differ depending on the depth of the makefile 87 def fix_MakeLevel(file) : 88 if environ.get('MAKELEVEL') : 89 file_replace(file, "make\[%i\]" % int(environ.get('MAKELEVEL')), 'make' ) 90 91 # helper function to check if a files contains only a spacific string 92 def fileContainsOnly(file, text) : 93 with open(file) as f: 94 ff = f.read().strip() 95 result = ff == text.strip() 96 97 return result; 98 99 # check whether or not a file is executable 100 def fileIsExecutable(file) : 101 try : 102 fileinfo = os.stat(file) 103 return bool(fileinfo.st_mode & stat.S_IXUSR) 104 except Exception as inst: 105 print(type(inst)) # the exception instance 106 print(inst.args) # arguments stored in .args 107 print(inst) 108 return False 69 # from the found tests, filter all the valid tests/desired tests 70 def validTests( options ): 71 tests = [] 72 73 # if we are regenerating the tests we need to find the information of the 74 # already existing tests and create new info for the new tests 75 if options.regenerate_expected : 76 for testname in options.tests : 77 if testname.endswith( (".c", ".cc", ".cpp") ): 78 print('ERROR: "%s", tests are not allowed to end with a C/C++/CFA extension, ignoring it' % testname, file=sys.stderr) 79 else : 80 found = [test for test in allTests if test.name == testname] 81 tests.append( found[0] if len(found) == 1 else Test(testname, testname) ) 82 83 else : 84 # otherwise we only need to validate that all tests are present in the complete list 85 for testname in options.tests: 86 test = [t for t in allTests if t.name == testname] 87 88 if len(test) != 0 : 89 tests.append( test[0] ) 90 else : 91 print('ERROR: No expected file for test %s, ignoring it' % testname, file=sys.stderr) 92 93 # make sure we have at least some test to run 94 if len(tests) == 0 : 95 print('ERROR: No valid test to run', file=sys.stderr) 96 sys.exit(1) 97 98 return tests 99 100 # parses the option 101 def getOptions(): 102 # create a parser with the arguments for the tests script 103 parser = argparse.ArgumentParser(description='Script which runs cforall tests') 104 parser.add_argument('--debug', help='Run all tests in debug or release', type=yes_no, default='no') 105 parser.add_argument('--concurrent', help='Run concurrent tests', type=yes_no, default='yes') 106 parser.add_argument('--dry-run', help='Don\'t run the tests, only output the commands', action='store_true') 107 parser.add_argument('--list', help='List all test available', action='store_true') 108 parser.add_argument('--all', help='Run all test available', action='store_true') 109 parser.add_argument('--regenerate-expected', help='Regenerate the .expect by running the specified tets, can be used with --all option', action='store_true') 110 parser.add_argument('-j', '--jobs', help='Number of tests to run simultaneously', type=int, default='8') 111 parser.add_argument('--list-comp', help='List all valide arguments', action='store_true') 112 parser.add_argument('tests', metavar='test', type=str, nargs='*', help='a list of tests to run') 113 114 options = parser.parse_args() 115 116 # script must have at least some tests to run or be listing 117 listing = options.list or options.list_comp 118 all_tests = options.all 119 some_tests = len(options.tests) > 0 120 121 # check that exactly one of the booleans is set to true 122 if not sum( (listing, all_tests, some_tests) ) == 1 : 123 print('ERROR: must have option \'--all\', \'--list\' or non-empty test list', file=sys.stderr) 124 parser.print_help() 125 sys.exit(1) 126 127 return options 128 129 def jobCount( options ): 130 # check if the user already passed in a number of jobs for multi-threading 131 make_flags = environ.get('MAKEFLAGS') 132 make_jobs_fds = re.search("--jobserver-(auth|fds)=\s*([0-9]+),([0-9]+)", make_flags) if make_flags else None 133 if make_jobs_fds : 134 tokens = os.read(int(make_jobs_fds.group(2)), 1024) 135 options.jobs = len(tokens) 136 os.write(int(make_jobs_fds.group(3)), tokens) 137 else : 138 options.jobs = multiprocessing.cpu_count() 139 140 # make sure we have a valid number of jobs that corresponds to user input 141 if options.jobs <= 0 : 142 print('ERROR: Invalid number of jobs', file=sys.stderr) 143 sys.exit(1) 144 145 return min( options.jobs, len(tests) ), True if make_flags else False 109 146 110 147 ################################################################################ 111 148 # running test functions 112 149 ################################################################################ 150 # logic to run a single test and return the result (No handling of printing or other test framework logic) 113 151 def run_single_test(test, generate, dry_run, debug): 114 152 115 153 # find the output file based on the test name and options flag 116 154 out_file = (".out/%s.log" % test.name) if not generate else (".expect/%s.txt" % test.path) 155 err_file = ".err/%s.log" % test.name 117 156 118 157 # remove any outputs from the previous tests to prevent side effects 119 sh("rm -f %s" % out_file, dry_run) 120 sh("rm -f %s > /dev/null 2>&1" % test.name, dry_run) 121 122 options = "-debug" if debug else "-nodebug"; 158 rm( (out_file, test.name), dry_run ) 159 160 options = "-debug" if debug else "-nodebug" 123 161 124 162 # build, skipping to next test on error 125 make_ret, _ = sh("""%s EXTRA_FLAGS="-quiet %s" %s 2> %s 1> /dev/null""" % (make_cmd, options, test.name, out_file), dry_run)163 make_ret, _ = sh("""%s test=yes EXTRA_FLAGS="-quiet %s" %s 2> %s 1> /dev/null""" % (make_cmd, options, test.name, out_file), dry_run) 126 164 127 165 # if the make command succeds continue otherwise skip to diff … … 137 175 sh("cat %s > %s" % (test.name, out_file), dry_run) 138 176 177 else : 178 # command failed save the log to less temporary file 179 sh("mv %s %s" % (err_file, out_file), dry_run) 180 139 181 retcode = 0 140 182 error = None 141 142 # fix output to prevent make depth to cause issues143 fix_MakeLevel(out_file)144 183 145 184 if generate : … … 151 190 152 191 else : 153 # diff the output of the files154 diff_cmd = ("diff --old-group-format='\t\tmissing lines :\n"155 "%%<' \\\n"156 "--new-group-format='\t\tnew lines :\n"157 "%%>' \\\n"158 "--unchanged-group-format='%%=' \\"159 "--changed-group-format='\t\texpected :\n"160 "%%<\n"161 "\t\tgot :\n"162 "%%>' \\\n"163 "--new-line-format='\t\t%%dn\t%%L' \\\n"164 "--old-line-format='\t\t%%dn\t%%L' \\\n"165 "--unchanged-line-format='' \\\n"166 ".expect/%s.txt .out/%s.log")167 168 192 # fetch return code and error from the diff command 169 retcode, error = sh(diff_cmd % (test.path, test.name), dry_run, False)170 193 retcode, error = diff(".expect/%s.txt" % test.path, ".out/%s.log" % test.name, dry_run) 194 171 195 # clean the executable 172 196 sh("rm -f %s > /dev/null 2>&1" % test.name, dry_run) … … 174 198 return retcode, error 175 199 176 def run_test_instance(t, generate, dry_run, debug) : 177 try:178 # print formated name 179 name_txt = "%20s " % t.name180 181 #run the test instance and collect the result182 test_failed, error = run_single_test(t, generate, dry_run, debug) 183 184 # update output based on current action185 if generate : 186 failed_txt = "ERROR"187 success_txt = "Done"188 else :189 failed_txt = "FAILED"190 success_txt = "PASSED"191 192 #print result with error if needed193 text = name_txt + (failed_txt if test_failed else success_txt) 194 out = sys.stdout195 if error :196 text = text + "\n" + error197 out = sys.stderr198 199 print(text, file = out);200 sys.stdout.flush() 201 sys.stderr.flush()202 return test_failed203 204 except KeyboardInterrupt:205 test_failed = True 206 200 # run a single test and handle the errors, outputs, printing, exception handling, etc. 201 def run_test_worker(t, generate, dry_run, debug) : 202 203 signal.signal(signal.SIGINT, signal.SIG_DFL) 204 # print formated name 205 name_txt = "%20s " % t.name 206 207 #run the test instance and collect the result 208 test_failed, error = run_single_test(t, generate, dry_run, debug) 209 210 # update output based on current action 211 if generate : 212 failed_txt = "ERROR" 213 success_txt = "Done" 214 else : 215 failed_txt = "FAILED" 216 success_txt = "PASSED" 217 218 #print result with error if needed 219 text = name_txt + (failed_txt if test_failed else success_txt) 220 out = sys.stdout 221 if error : 222 text = text + "\n" + error 223 out = sys.stderr 224 225 print(text, file = out); 226 sys.stdout.flush() 227 sys.stderr.flush() 228 signal.signal(signal.SIGINT, signal.SIG_IGN) 229 230 return test_failed 207 231 208 232 # run the given list of tests with the given parameters … … 211 235 sh("%s clean > /dev/null 2>&1" % make_cmd, dry_run) 212 236 213 # make sure the required folder are present214 sh('mkdir -p .out .expect ', dry_run)237 # make sure the required folder are present 238 sh('mkdir -p .out .expect .err', dry_run) 215 239 216 240 if generate : 217 241 print( "Regenerate tests for: " ) 218 242 243 # create the executor for our jobs and handle the signal properly 244 original_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN) 245 pool = Pool(jobs) 246 signal.signal(signal.SIGINT, original_sigint_handler) 247 219 248 # for each test to run 220 pool = Pool(jobs)221 249 try : 222 results = pool.map_async(partial(run_test_ instance, generate=generate, dry_run=dry_run, debug=debug), tests ).get(9999)250 results = pool.map_async(partial(run_test_worker, generate=generate, dry_run=dry_run, debug=debug), tests ).get(3600) 223 251 except KeyboardInterrupt: 224 252 pool.terminate() … … 226 254 sys.exit(1) 227 255 228 # clean the workspace256 # clean the workspace 229 257 sh("%s clean > /dev/null 2>&1" % make_cmd, dry_run) 230 258 … … 235 263 return 0 236 264 237 def yes_no(string):238 if string == "yes" :239 return True240 if string == "no" :241 return False242 raise argparse.ArgumentTypeError(msg)243 return False244 245 265 246 266 ################################################################################ 247 267 # main loop 248 268 ################################################################################ 249 # create a parser with the arguments for the tests script 250 parser = argparse.ArgumentParser(description='Script which runs cforall tests') 251 parser.add_argument('--debug', help='Run all tests in debug or release', type=yes_no, default='no') 252 parser.add_argument('--concurrent', help='Run concurrent tests', type=yes_no, default='yes') 253 parser.add_argument('--dry-run', help='Don\'t run the tests, only output the commands', action='store_true') 254 parser.add_argument('--list', help='List all test available', action='store_true') 255 parser.add_argument('--all', help='Run all test available', action='store_true') 256 parser.add_argument('--regenerate-expected', help='Regenerate the .expect by running the specified tets, can be used with --all option', action='store_true') 257 parser.add_argument('-j', '--jobs', help='Number of tests to run simultaneously', type=int, default='8') 258 parser.add_argument('tests', metavar='test', type=str, nargs='*', help='a list of tests to run') 259 260 # parse the command line arguments 261 options = parser.parse_args() 262 263 # script must have at least some tests to run 264 if (len(options.tests) > 0 and options.all and not options.list) \ 265 or (len(options.tests) == 0 and not options.all and not options.list) : 266 print('ERROR: must have option \'--all\' or non-empty test list', file=sys.stderr) 267 parser.print_help() 268 sys.exit(1) 269 270 # fetch the liest of all valid tests 271 allTests = listTests( options.concurrent ) 272 273 # if user wants all tests than no other treatement of the test list is required 274 if options.all or options.list : 275 tests = allTests 276 277 else : 278 #otherwise we need to validate that the test list that was entered is valid 279 tests = [] 280 281 # if we are regenerating the tests we need to find the information of the 282 # already existing tests and create new info for the new tests 283 if options.regenerate_expected : 284 for testname in options.tests : 285 if testname.endswith(".c") or testname.endswith(".cc") or testname.endswith(".cpp") : 286 print('ERROR: "%s", tests are not allowed to end with a C/C++/CFA extension, ignoring it' % testname, file=sys.stderr) 287 else : 288 found = [test for test in allTests if test.name == testname] 289 tests.append( found[0] if len(found) == 1 else Test(testname, testname) ) 290 291 else : 292 # otherwise we only need to validate that all tests are present in the complete list 293 for testname in options.tests: 294 test = [t for t in allTests if t.name == testname] 295 296 if len(test) != 0 : 297 tests.append( test[0] ) 298 else : 299 print('ERROR: No expected file for test %s, ignoring it' % testname, file=sys.stderr) 300 301 # make sure we have at least some test to run 302 if len(tests) == 0 : 303 print('ERROR: No valid test to run', file=sys.stderr) 304 sys.exit(1) 305 306 # sort the test alphabetically for convenience 307 tests.sort(key=lambda t: t.name) 308 309 # check if the user already passed in a number of jobs for multi-threading 310 make_flags = environ.get('MAKEFLAGS') 311 make_jobs_fds = re.search("--jobserver-fds=\s*([0-9]+),([0-9]+)", make_flags) if make_flags else None 312 if make_jobs_fds : 313 tokens = os.read(int(make_jobs_fds.group(1)), 1024) 314 options.jobs = len(tokens) 315 os.write(int(make_jobs_fds.group(2)), tokens) 316 317 # make sure we have a valid number of jobs that corresponds to user input 318 if options.jobs <= 0 : 319 print('ERROR: Invalid number of jobs', file=sys.stderr) 320 sys.exit(1) 321 322 print('Running (%s) on %i cores' % ("debug" if options.debug else "no debug", options.jobs)) 323 make_cmd = "make" if make_flags else ("make -j%i" % options.jobs) 324 325 # users may want to simply list the tests 326 if options.list : 327 print("\n".join(map(lambda t: "%s (%s)" % (t.name, t.path), tests))) 328 329 else : 330 # otherwise run all tests and make sure to return the correct error code 331 sys.exit( run_tests(tests, options.regenerate_expected, options.dry_run, options.jobs, options.debug) ) 269 if __name__ == "__main__": 270 #always run from same folder 271 chdir() 272 273 # parse the command line arguments 274 options = getOptions() 275 276 # fetch the liest of all valid tests 277 allTests = listTests( options.concurrent ) 278 279 # if user wants all tests than no other treatement of the test list is required 280 if options.all or options.list or options.list_comp : 281 tests = allTests 282 283 else : 284 #otherwise we need to validate that the test list that was entered is valid 285 tests = validTests( options ) 286 287 # sort the test alphabetically for convenience 288 tests.sort(key=lambda t: t.name) 289 290 # users may want to simply list the tests 291 if options.list_comp : 292 print("-h --help --debug --concurrent --dry-run --list --all --regenerate-expected -j --jobs ", end='') 293 print(" ".join(map(lambda t: "%s" % (t.name), tests))) 294 295 elif options.list : 296 print("\n".join(map(lambda t: "%s (%s)" % (t.name, t.path), tests))) 297 298 else : 299 options.jobs, forceJobs = jobCount( options ) 300 301 print('Running (%s) on %i cores' % ("debug" if options.debug else "no debug", options.jobs)) 302 make_cmd = "make" if forceJobs else ("make -j%i" % options.jobs) 303 304 # otherwise run all tests and make sure to return the correct error code 305 sys.exit( run_tests(tests, options.regenerate_expected, options.dry_run, options.jobs, options.debug) )
Note: See TracChangeset
for help on using the changeset viewer.