Changes in / [26d40a1:d1f5054]


Ignore:
Files:
4 added
3 deleted
16 edited

Legend:

Unmodified
Added
Removed
  • doc/bibliography/pl.bib

    r26d40a1 rd1f5054  
    30883088    note        = {WikipediA},
    30893089    howpublished= {\url{http://www.akkadia.org/drepper/tls.pdf}},
     3090}
     3091
     3092@misc{DARPA24,
     3093    contributer = {pabuhr@plg},
     3094    title       = {Eliminating Memory Safety Vulnerabilities Once and For All},
     3095    author      = {Defense Advanced Research Projects Agency},
     3096    year        = 2024,
     3097    month       = jul,
     3098    howpublished= {\url{https://www.darpa.mil/news-events/2024-07-31a}},
    30903099}
    30913100
     
    76867695}
    76877696
     7697@misc{WhiteHouse24,
     7698    contributer = {pabuhr@plg},
     7699    title       = {Part {II}: Securing the Building Blocks of Cyberspace},
     7700    author      = {U.S. Federal Government},
     7701    year        = 2024,
     7702    howpublished= {\url{https://www.whitehouse.gov/wp-content/uploads/2024/02/Final-ONCD-Technical-Report.pdf}},
     7703}
     7704
    76887705@inproceedings{Chen07,
    76897706    keywords    = {chip multiprocessors, constructive cache sharing, parallel depth first, scheduling algorithms, thread granularity, work stealing, working set profiling},
  • doc/theses/jiada_liang_MMath/test1.cfa

    r26d40a1 rd1f5054  
    11#include <fstream.hfa>                                                                  // sout
    22#include <stdlib.hfa>                                                                   // ato
     3#include <enum.hfa>
    34
    45// integral
     
    910enum( Letter ) Greek { Alph = A, Beta = B, Gamma = G, /* more enums */ Zeta = Z }; // alphabet intersection
    1011
     12// integral
    1113enum( char ) Currency { Dollar = '$', Cent = '¢', Yen = '¥', Pound = '£', Euro = 'E' }; // iso-latin-1
    1214enum( Currency ) Europe { Euro = Currency.Euro, Pound = Currency.Pound };
     
    3335
    3436enum() Mode { O_RDONLY, O_WRONLY, O_CREAT, O_TRUNC, O_APPEND };
    35 Mode iomode = O_RDONLY;
    36 //bool b = iomode == O_RDONLY || iomode < O_APPEND;     // disallowed
    37 //int www = iomode;     // disallowed
     37Mode mode = O_RDONLY;
     38void opaque() {
     39bool b = mode == O_RDONLY || mode < O_APPEND;   // disallowed
     40//int www = mode;       // disallowed
     41}
    3842
    3943enum( char * ) Colour { Red = "red", Green = "green", Blue = "blue"  };
     44
     45enum E1 { A1, B1, C1 = A1, D1 = B1 };
     46enum(float) E2 { A2 = 3.5, B2 = 4.5, C2 = A, D2 = B };
    4047
    4148void fred() {
     
    4552//greek = A;                                                            // disallowed
    4653
    47         for ( Greek l = Alph; posn(l) <= posn(Gamma); l = succ( l ) ) {
     54        for ( Greek l = Alph; posn(l) < posn(Gamma); l = succ( l ) ) {
    4855                printf( "%s %c %d\n", label( l ), value( l ), posn( l ) );
    4956        }
    50         for ( Currency c = Dollar; posn(c) <= posn(Currency.Euro); c = succ( c ) ) {
     57        for ( Currency c = Dollar; posn(c) < posn(Currency.Euro); c = succ( c ) ) {
    5158                printf( "%s %c %d\n", label( c ), value( c ), posn( c ) );
    5259        }
    5360}
    5461
    55 
    56 enum( char * ) Names { Fred = "FRED", Mary = "MARY", Jane = "JANE" };
    57 enum( char * ) Names2 { inline Names, Jack = "JACK", Jill = "JILL" };
    58 enum( char * ) Names3 { inline Names2, Sue = "SUE", Tom = "TOM" };
    59 
     62enum( const char * ) Names { Fred = "FRED", Mary = "MARY", Jane = "JANE" };
     63enum( const char * ) Names2 { inline Names, Jack = "JACK", Jill = "JILL" };
     64enum( const char * ) Names3 { inline Names2, Sue = "SUE", Tom = "TOM" };
     65void bar() {
     66        Names fred = Names.Fred;
     67        (Names2)fred;  (Names3)fred;  (Names3)Names2.Jack;  // cast to super type
     68        Names2 fred2 = fred;  Names3 fred3 = fred2; // assign to super type
     69        const char * name = fred;
     70        Names name = Fred;
     71        sout | name | label( name ) | posn( name ) | value( name );
     72}
    6073void f( Names n ) { sout | "Name" | posn( n ); }
    6174void g( Names2 );
     
    6376void j( char * );
    6477
    65 enum color { red, blue, green };
    66 //color c = 0;
    67 //color c = 1;
    68 color c = 2;
    69 int w = red;
     78enum CColour { Red, Blue, Green };
     79CColour c0 = 0;
     80CColour c1 = 1;
     81CColour c = 2;
     82int w = Red;
     83
     84void coo() {
     85        enum(int) Color { Red, Blue, Green };
     86        Colour c = Red;
     87        sout | countof( Colour ) | Countof( c );
     88//      sout | Countof( Colour );
     89        sout | countof( c );
     90}
    7091
    7192// enum(int) Week ! { Mon, Tue, Wed, Thu = 10, Fri, Sat, Sun };
     
    79100// }
    80101
     102void baz() {
     103        enum(int) Count { First, Second, Third/* = First*/, Fourth/* = Second*/ };
     104        enum CCount { First, Second, Third/* = First*/, Fourth/* = Second*/ };
     105        Count cnt = Second;
     106        CCount ccnt = Second;
     107        if ( cnt < Third ) sout | "less than Third";
     108        if ( cnt ) sout | "XXX";
     109        if ( ccnt ) sout | "YYY";
     110        enum(float) F {WWW = 0.0};
     111        F f;
     112        if ( f ) sout | "FFF";
     113        bool ?!=?( Name n, zero_t ) { sout | "DDD";  return n != Fred; }
     114        Name n = Mary;
     115        if ( n ) sout | "NAME";
     116        choose( cnt ) {
     117                case First: sout | "First";
     118                case Second: sout | "Second";
     119                case Third: sout | "Third";
     120                case Fourth: sout | "Fourth";
     121        }
     122//      for (d; Week) { sout | d; }
     123//      for (p; +~=Planet) { sout | p; }
     124        for ( cx; Count ) { sout | cx | nonl; } sout | nl;
     125        for ( cx; +~= Count ) { sout | cx | nonl; } sout | nl;
     126        for ( cx; -~= Count ) { sout | cx | nonl; } sout | nl;
     127        for ( Count cx = lowerBound();; ) {
     128                sout | cx | nonl;
     129          if ( cx == upperBound() ) break;
     130                cx = succ( cx );
     131        }
     132        sout | nl;
     133}
     134
    81135int main() {
    82136        fred();
    83         Names name = Fred;
     137        Names name = Names.Fred;
    84138//      f( name );
    85139
    86140        int jane_pos = posn( Names.Jane );
    87         char * jane_value = value( Names.Jane );
    88         char * jane_label = label( Names.Jane );
     141        const char * jane_value = value( Names.Jane );
     142        const char * jane_label = label( Names.Jane );
    89143        sout | Names.Jane | posn( Names.Jane) | label( Names.Jane ) | value( Names.Jane );
     144
     145        bar();
     146        baz();
     147        coo();
     148
     149        enum Ex { Ax, Bx, Cx, Nx };
     150        float H1[Nx] = { [Ax] : 3.4, [Bx] : 7.1, [Cx] : 0.01 }; // C
     151//      float H2[Ex] = { [Ax] : 3.4, [Bx] : 7.1, [Cx] : 0.01 }; // CFA
     152
     153        enum(int) E { A = 3 } e = A;
     154        sout | A | label( A ) | posn( A ) | value( A );
     155        sout | e | label( e ) | posn( e ) | value( e );
    90156}
  • doc/theses/mike_brooks_MMath/background.tex

    r26d40a1 rd1f5054  
    22
    33Since this work builds on C, it is necessary to explain the C mechanisms and their shortcomings for array, linked list, and string.
     4
     5
     6\section{Ill-typed expressions}
     7
     8C reports many ill-typed expressions as warnings.
     9For example, these attempts to assign @y@ to @x@ and vice-versa are obviously ill-typed.
     10\lstinput{12-15}{bkgd-c-tyerr.c}
     11with warnings:
     12\begin{cfa}
     13warning: assignment to 'float *' from incompatible pointer type 'void (*)(void)'
     14warning: assignment to 'void (*)(void)' from incompatible pointer type 'float *'
     15\end{cfa}
     16Similarly,
     17\lstinput{17-19}{bkgd-c-tyerr.c}
     18with warning:
     19\begin{cfa}
     20warning: passing argument 1 of 'f' from incompatible pointer type
     21note: expected 'void (*)(void)' but argument is of type 'float *'
     22\end{cfa}
     23with a segmentation fault at runtime.
     24Clearly, @gcc@ understands these ill-typed case, and yet allows the program to compile, which seems inappropriate.
     25Compiling with flag @-Werror@, which turns warnings into errors, is often too strong, because some warnings are just warnings, \eg unused variable.
     26In the following discussion, ``ill-typed'' means giving a nonzero @gcc@ exit condition with a message that discusses typing.
     27Note, \CFA's type-system rejects all these ill-typed cases as type mismatch errors.
     28
     29% That @f@'s attempt to call @g@ fails is not due to 3.14 being a particularly unlucky choice of value to put in the variable @pi@.
     30% Rather, it is because obtaining a program that includes this essential fragment, yet exhibits a behaviour other than "doomed to crash," is a matter for an obfuscated coding competition.
     31
     32% A "tractable syntactic method for proving the absence of certain program behaviours by classifying phrases according to the kinds of values they compute"*1 rejected the program.
     33% The behaviour (whose absence is unprovable) is neither minor nor unlikely.
     34% The rejection shows that the program is ill-typed.
     35%
     36% Yet, the rejection presents as a GCC warning.
     37% *1  TAPL-pg1 definition of a type system
    438
    539
  • doc/theses/mike_brooks_MMath/intro.tex

    r26d40a1 rd1f5054  
    11\chapter{Introduction}
    22
    3 All modern programming languages provide three high-level containers (collection): array, linked-list, and string.
    4 Often array is part of the programming language, while linked-list is built from pointer types, and string from a combination of array and linked-list.
    5 For all three types, there is some corresponding mechanism for iterating through the structure, where the iterator flexibility varies with the kind of structure and ingenuity of the iterator implementor.
     3All modern programming languages provide three high-level containers (collections): array, linked-list, and string.
     4Often array is part of the programming language, while linked-list is built from (recursive) pointer types, and string from a combination of array and linked-list.
     5For all three types, languages supply varying degrees of high-level mechanism for manipulating these objects at the bulk level and at the component level, such as array copy, slicing and iterating.
     6
     7This work looks at extending these three foundational container types in the programming language \CFA, which is a new dialect of the C programming language.
     8A primary goal of \CFA~\cite{Cforall} is 99\% backward compatibility with C, while maintaining a look and feel that matches with C programmer experience and intuition.
     9This goal requires ``thinking inside the box'' to engineer new features that ``work and play'' with C and its massive legacy code-base.
     10An additional goal is balancing good performance with safety.
    611
    712
    813\section{Array}
    914
    10 An array provides a homogeneous container with $O(1)$ access to elements using subscripting (some form of pointer arithmetic).
     15An array provides a homogeneous container with $O(1)$ access to elements using subscripting.
    1116The array size can be static, dynamic but fixed after creation, or dynamic and variable after creation.
    1217For static and dynamic-fixed, an array can be stack allocated, while dynamic-variable requires the heap.
    13 Because array layout has contiguous components, subscripting is a computation.
    14 However, the computation can exceed the array bounds resulting in programming errors and security violations~\cite{Elliott18, Blache19, Ruef19, Oorschot23}.
    15 The goal is to provide good performance with safety.
     18Because array layout has contiguous components, subscripting is a computation (some form of pointer arithmetic).
    1619
    1720
    1821\section{Linked list}
    1922
    20 A linked-list provides a homogeneous container often with $O(log N)$/$O(N)$ access to elements using successor and predecessor operations.
     23A linked-list provides a homogeneous container often with $O(log N)$/$O(N)$ access to elements using successor and predecessor operations that normally involve pointer chasing.
    2124Subscripting by value is sometimes available, \eg hash table.
    2225Linked types are normally dynamically sized by adding/removing nodes using link fields internal or external to the elements (nodes).
    2326If a programming language allows pointer to stack storage, linked-list types can be allocated on the stack;
    24 otherwise, elements are heap allocated and explicitly/implicitly managed.
     27otherwise, elements are heap allocated with explicitly/implicitly managed.
    2528
    2629
     
    2831
    2932A string provides a dynamic array of homogeneous elements, where the elements are often human-readable characters.
    30 What differentiates a string from other types in that its operations work on blocks of elements for scanning and changing the elements, rather than accessing individual elements, \eg @index@ and @substr@.
     33What differentiates a string from other types in that its operations work on blocks of elements for scanning and changing, \eg @index@ and @substr@.
    3134Subscripting individual elements is often available.
    32 Often the cost of string operations is less important than the power of the operations to accomplish complex text manipulation, \eg search, analysing, composing, and decomposing.
     35Therefore, the cost of string operations is less important than the power of the operations to accomplish complex text manipulation, \eg search, analysing, composing, and decomposing.
    3336The dynamic nature of a string means storage is normally heap allocated but often implicitly managed, even in unmanaged languages.
     37Often string management is separate from heap management, \ie strings roll their own heap.
    3438
    3539
    3640\section{Motivation}
    3741
    38 The goal of this work is to introduce safe and complex versions of array, link lists, and strings into the programming language \CFA~\cite{Cforall}, which is based on C.
    39 Unfortunately, to make C better, while retaining a high level of backwards compatibility, requires a significant knowledge of C's design.
    40 Hence, it is assumed the reader has a medium knowledge of C or \CC, on which extensive new C knowledge is built.
     42The primary motivation for this work is two fold:
     43\begin{enumerate}[leftmargin=*]
     44\item
     45These three aspects of C are extremely difficult to understand, teach, and get right because they are correspondingly extremely low level.
     46Providing higher-level versions of these containers in \CFA is a major component of the primary goal.
     47\item
     48These three aspects of C cause the greatest safety issues because there are few or no safe guards when a programmer misunderstands or misuses these features~\cite{Elliott18, Blache19, Ruef19, Oorschot23}.
     49Estimates suggest 50\%~\cite{Mendio24} of total reported open-source vulnerabilities occur in C resulting from errors using these facilities (memory errors), providing the major hacker attack-vectors.
     50\end{enumerate}
     51Both White House~\cite{WhiteHouse24} and DARPA~\cite{DARPA24} recently released a recommendation to move away from C and \CC, because of cybersecurity threats exploiting vulnerabilities in these older languages.
     52Hardening these three types goes a long way to make the majority of C programs safer.
     53
     54
     55While multiple new languages purport to be systems languages replacing C, the reality is that rewriting massive C code-bases is impractical and a non-starter if the new runtime uses garage collection.
     56Furthermore, these languages must still interact with the underlying C operating system through fragile, type-unsafe, interlanguage-communication.
     57Switching to \CC is equally impractical as its complex and interdependent type-system (\eg objects, inheritance, templates) means idiomatic \CC code is difficult to use from C, and C programmers must expend significant effort learning \CC.
     58Hence, rewriting and retraining costs for these languages can be prohibitive for companies with a large C software-base (Google, Apple, Microsoft, Amazon, AMD, Nvidia).
    4159
    4260
     
    4664However, most programming languages are only partially explained by standard's manuals.
    4765When it comes to explaining how C works, the definitive source is the @gcc@ compiler, which is mimicked by other C compilers, such as Clang~\cite{clang}.
    48 Often other C compilers must mimic @gcc@ because a large part of the C library (runtime) system contains @gcc@ features.
    49 While some key aspects of C need to be explained by quoting from the language reference manual, to illustrate definite program semantics, I devise a program, whose behaviour exercises the point at issue, and shows its behaviour.
     66Often other C compilers must mimic @gcc@ because a large part of the C library (runtime) system (@glibc@ on Linux) contains @gcc@ features.
     67While some key aspects of C need to be explained by quoting from the language reference manual, to illustrate definite program semantics, my approach in this thesis is to devise a program, whose behaviour exercises a point at issue, and shows its behaviour.
    5068These example programs show
    51 \begin{itemize}
    52         \item the compiler accepts or rejects certain syntax,
     69\begin{itemize}[leftmargin=*]
     70        \item if the compiler accepts or rejects certain syntax,
    5371        \item prints output to buttress a claim of behaviour,
    54         \item executes without triggering any embedded assertions testing pre/post-assertions or invariants.
     72        \item or executes without triggering any embedded assertions testing pre/post-assertions or invariants.
    5573\end{itemize}
    5674This work has been tested across @gcc@ versions 8--12 and clang version 10 running on ARM, AMD, and Intel architectures.
    5775Any discovered anomalies among compilers or versions is discussed.
    58 In all case, I do not argue that my sample of major Linux compilers is doing the right thing with respect to the C standard.
    59 
    60 
    61 \subsection{Ill-typed expressions}
    62 
    63 C reports many ill-typed expressions as warnings.
    64 For example, these attempts to assign @y@ to @x@ and vice-versa are obviously ill-typed.
    65 \lstinput{12-15}{bkgd-c-tyerr.c}
    66 with warnings:
    67 \begin{cfa}
    68 warning: assignment to 'float *' from incompatible pointer type 'void (*)(void)'
    69 warning: assignment to 'void (*)(void)' from incompatible pointer type 'float *'
    70 \end{cfa}
    71 Similarly,
    72 \lstinput{17-19}{bkgd-c-tyerr.c}
    73 with warning:
    74 \begin{cfa}
    75 warning: passing argument 1 of 'f' from incompatible pointer type
    76 note: expected 'void (*)(void)' but argument is of type 'float *'
    77 \end{cfa}
    78 with a segmentation fault at runtime.
    79 Clearly, @gcc@ understands these ill-typed case, and yet allows the program to compile, which seems inappropriate.
    80 Compiling with flag @-Werror@, which turns warnings into errors, is often too strong, because some warnings are just warnings, \eg unsed variable.
    81 In the following discussion, ``ill-typed'' means giving a nonzero @gcc@ exit condition with a message that discusses typing.
    82 Note, \CFA's type-system rejects all these ill-typed cases as type mismatch errors.
    83 
    84 % That @f@'s attempt to call @g@ fails is not due to 3.14 being a particularly unlucky choice of value to put in the variable @pi@.
    85 % Rather, it is because obtaining a program that includes this essential fragment, yet exhibits a behaviour other than "doomed to crash," is a matter for an obfuscated coding competition.
    86 
    87 % A "tractable syntactic method for proving the absence of certain program behaviours by classifying phrases according to the kinds of values they compute"*1 rejected the program.
    88 % The behaviour (whose absence is unprovable) is neither minor nor unlikely.
    89 % The rejection shows that the program is ill-typed.
    90 %
    91 % Yet, the rejection presents as a GCC warning.
    92 % *1  TAPL-pg1 definition of a type system
     76In all case, it is never clear whether the \emph{truth} lies in the compiler or the C standard.
    9377
    9478
  • doc/theses/mike_brooks_MMath/string.tex

    r26d40a1 rd1f5054  
    11\chapter{String}
    22
    3 \section{String}
     3
     4
     5
    46
    57\subsection{Logical overlap}
  • doc/theses/mike_brooks_MMath/uw-ethesis.bib

    r26d40a1 rd1f5054  
    114114    pages       = {53-60},
    115115}
     116
     117
     118@misc{Mendio24,
     119    contributer = {pabuhr@plg},
     120    title       = {What are the most secure programming languages?},
     121    author      = {Mend.io (White Source Ltd.)},
     122    year        = 2024,
     123    howpublished= {\url{https://www.mend.io/most-secure-programming-languages}},
     124}
  • libcfa/src/concurrency/io/call.cfa.in

    r26d40a1 rd1f5054  
    214214        __attribute__((unused)) bool parked;
    215215        parked = wait( future );
     216#if defined(CFA_HAVE_LINUX_IO_URING_H)
    216217        __STATS__(false, if(!parked) io.submit.nblk += 1; )
     218#endif
    217219        if( future.result < 0 ) {{
    218220                errno = -future.result;
  • src/AST/Expr.hpp

    r26d40a1 rd1f5054  
    1111// Last Modified By : Peter A. Buhr
    1212// Created On       : Fri May 10 10:30:00 2019
    13 // Update Count     : 7
     13// Update Count     : 8
    1414//
    1515
     
    8686
    8787                /// initializes from other InferUnion
    88                 void init_from( const InferUnion& o ) {
     88                void init_from( const InferUnion & o ) {
    8989                        if (o.data.resnSlots) {
    9090                                data.resnSlots = new ResnSlots(*o.data.resnSlots);
     
    9696
    9797                /// initializes from other InferUnion (move semantics)
    98                 void init_from( InferUnion&& o ) {
     98                void init_from( InferUnion && o ) {
    9999                        data.resnSlots = o.data.resnSlots;
    100100                        data.inferParams = o.data.inferParams;
     
    104104
    105105                InferUnion() : mode(Empty), data() {}
    106                 InferUnion( const InferUnion& o ) : mode( o.mode ), data() { init_from( o ); }
    107                 InferUnion( InferUnion&& o ) : mode( o.mode ), data() { init_from( std::move(o) ); }
    108                 InferUnion& operator= ( const InferUnion& ) = delete;
    109                 InferUnion& operator= ( InferUnion&& ) = delete;
     106                InferUnion( const InferUnion & o ) : mode( o.mode ), data() { init_from( o ); }
     107                InferUnion( InferUnion && o ) : mode( o.mode ), data() { init_from( std::move(o) ); }
     108                InferUnion & operator= ( const InferUnion & ) = delete;
     109                InferUnion & operator= ( InferUnion && ) = delete;
    110110
    111111                bool hasSlots() const { return data.resnSlots; }
    112112                bool hasParams() const { return data.inferParams; }
    113113
    114                 ResnSlots& resnSlots() {
     114                ResnSlots & resnSlots() {
    115115                        if (!data.resnSlots) {
    116116                                data.resnSlots = new ResnSlots();
     
    119119                }
    120120
    121                 const ResnSlots& resnSlots() const {
     121                const ResnSlots & resnSlots() const {
    122122                        if (data.resnSlots) {
    123123                                return *data.resnSlots;
     
    127127                }
    128128
    129                 InferredParams& inferParams() {
     129                InferredParams & inferParams() {
    130130                        if (!data.inferParams) {
    131131                                data.inferParams = new InferredParams();
     
    134134                }
    135135
    136                 const InferredParams& inferParams() const {
     136                const InferredParams & inferParams() const {
    137137                        if (data.inferParams) {
    138138                                return *data.inferParams;
     
    669669        ptr<ApplicationExpr> callExpr;
    670670
    671         ImplicitCopyCtorExpr( const CodeLocation& loc, const ApplicationExpr * call )
     671        ImplicitCopyCtorExpr( const CodeLocation & loc, const ApplicationExpr * call )
    672672        : Expr( loc, call->result ), callExpr(call) { assert( call ); assert(call->result); }
    673673
  • src/CodeGen/CodeGenerator.cpp

    r26d40a1 rd1f5054  
    7979                currentLocation.first_line += 2;
    8080        } else {
    81                 output << "\n# " << to.first_line << " \"" << to.filename
     81                output << "\n# " << to.first_line << " \"" << to.filename.c_str()
    8282                       << "\"\n" << indent;
    8383                currentLocation = to;
  • src/Common/CodeLocation.hpp

    r26d40a1 rd1f5054  
    1717
    1818#include <iostream>
    19 #include <string>
     19#include "Symbol.hpp"
    2020
    2121struct CodeLocation {
    2222        int first_line = -1, first_column = -1, last_line = -1, last_column = -1;
    23         std::string filename = "";
     23        Symbol filename = "";
    2424
    2525        /// Create a new unset CodeLocation.
     
    4646
    4747        bool startsBefore( CodeLocation const & other ) const {
    48                 if( filename < other.filename ) return true;
    49                 if( filename > other.filename ) return false;
     48                if( filename.str() < other.filename.str() ) return true;
     49                if( filename.str() > other.filename.str() ) return false;
    5050
    5151                if( first_line < other.first_line ) return true;
     
    7272inline std::ostream & operator<<( std::ostream & out, const CodeLocation & location ) {
    7373        // Column number ":1" allows IDEs to parse the error message and position the cursor in the source text.
    74         return location.isSet() ? out << location.filename << ":" << location.first_line << ":1 " : out;
     74        return location.isSet() ? out << location.filename.str() << ":" << location.first_line << ":1 " : out;
    7575}
  • src/Common/module.mk

    r26d40a1 rd1f5054  
    4848        Common/Stats/Time.cpp \
    4949        Common/Stats/Time.hpp \
     50        Common/Symbol.cpp \
     51        Common/Symbol.hpp \
    5052        Common/ToString.hpp \
    5153        Common/UniqueName.cpp \
  • src/GenPoly/Lvalue.cpp

    r26d40a1 rd1f5054  
    1010// Created On       : Thu Sep 15 14:08:00 2022
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Oct  6  9:59:00 2022
    13 // Update Count     : 0
     12// Last Modified On : Mon Aug 12 18:07:00 2024
     13// Update Count     : 1
    1414//
    1515
     
    119119/// Replace all reference types with pointer types.
    120120struct ReferenceTypeElimination final {
     121        ast::SizeofExpr const * previsit( ast::SizeofExpr const * expr );
     122        ast::AlignofExpr const * previsit( ast::AlignofExpr const * expr );
    121123        ast::Type const * postvisit( ast::ReferenceType const * type );
    122124};
     
    603605}
    604606
     607ast::SizeofExpr const * ReferenceTypeElimination::previsit(
     608                ast::SizeofExpr const * expr ) {
     609        if ( expr->expr ) return expr;
     610        return ast::mutate_field( expr, &ast::SizeofExpr::type,
     611                expr->type->stripReferences() );
     612}
     613
     614ast::AlignofExpr const * ReferenceTypeElimination::previsit(
     615                ast::AlignofExpr const * expr ) {
     616        if ( expr->expr ) return expr;
     617        return ast::mutate_field( expr, &ast::AlignofExpr::type,
     618                expr->type->stripReferences() );
     619}
     620
    605621ast::Type const * ReferenceTypeElimination::postvisit(
    606622                ast::ReferenceType const * type ) {
  • src/InitTweak/FixInit.cpp

    r26d40a1 rd1f5054  
    731731        try {
    732732                mutLast->expr = makeCtorDtor( "?{}", ret, mutLast->expr );
    733         } catch(...) {
     733        } catch (...) {
    734734                std::cerr << "*CFA internal error: ";
    735735                std::cerr << "can't resolve implicit constructor";
    736                 std::cerr << " at " << stmtExpr->location.filename;
     736                std::cerr << " at " << stmtExpr->location.filename.c_str();
    737737                std::cerr << ":" << stmtExpr->location.first_line << std::endl;
    738738
  • src/Parser/parser.yy

    r26d40a1 rd1f5054  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 26 14:09:30 2024
    13 // Update Count     : 6733
     12// Last Modified On : Tue Aug 13 11:25:16 2024
     13// Update Count     : 6740
    1414//
    1515
     
    952952                }
    953953        | COUNTOF unary_expression
    954                 {  $$ = new ExpressionNode( new ast::CountExpr( yylloc, maybeMoveBuild( $2 ) ) ); }
     954                { $$ = new ExpressionNode( new ast::CountExpr( yylloc, maybeMoveBuild( $2 ) ) ); }
    955955        | COUNTOF '(' type_no_function ')'
    956956                { $$ = new ExpressionNode( new ast::CountExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
     
    16261626enum_key:
    16271627        type_name
    1628                 {       typedefTable.makeTypedef( *$1->symbolic.name, "enum_type_nobody 1" );
    1629                         $$ = DeclarationNode::newEnum( $1->symbolic.name, nullptr, false, false ); }
     1628                {
     1629                        typedefTable.makeTypedef( *$1->symbolic.name, "enum_type_nobody 1" );
     1630                        $$ = DeclarationNode::newEnum( $1->symbolic.name, nullptr, false, false );
     1631                }
    16301632        | ENUM identifier
    1631                 {       typedefTable.makeTypedef( *$2, "enum_type_nobody 2" );
    1632                         $$ = DeclarationNode::newEnum( $2, nullptr, false, false ); }
     1633                {
     1634                        typedefTable.makeTypedef( *$2, "enum_type_nobody 2" );
     1635                        $$ = DeclarationNode::newEnum( $2, nullptr, false, false );
     1636                }
    16331637        | ENUM type_name
    1634                 {       typedefTable.makeTypedef( *$2->symbolic.name, "enum_type_nobody 3" );
    1635                         $$ = DeclarationNode::newEnum( $2->symbolic.name, nullptr, false, false ); }
     1638                {
     1639                        typedefTable.makeTypedef( *$2->symbolic.name, "enum_type_nobody 3" );
     1640                        $$ = DeclarationNode::newEnum( $2->symbolic.name, nullptr, false, false );
     1641                }
    16361642        ;
    16371643
     
    18491855
    18501856handler_clause:
    1851         handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement
    1852                 { $$ = new ClauseNode( build_catch( yylloc, $1, $4, $6, $8 ) ); }
    1853         | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement
    1854                 { $$ = $1->set_last( new ClauseNode( build_catch( yylloc, $2, $5, $7, $9 ) ) ); }
     1857        handler_key '(' exception_declaration handler_predicate_opt ')' compound_statement
     1858                { $$ = new ClauseNode( build_catch( yylloc, $1, $3, $4, $6 ) ); }
     1859        | handler_clause handler_key '(' exception_declaration handler_predicate_opt ')' compound_statement
     1860                { $$ = $1->set_last( new ClauseNode( build_catch( yylloc, $2, $4, $5, $7 ) ) ); }
    18551861        ;
    18561862
     
    28502856
    28512857enumerator_list:
    2852         visible_hide_opt identifier_or_type_name enumerator_value_opt
     2858        // empty
     2859                { SemanticError( yylloc, "enumeration must have a minimum of one enumerator, empty enumerator list is meaningless." );  $$ = nullptr; }
     2860        | visible_hide_opt identifier_or_type_name enumerator_value_opt
    28532861                { $$ = DeclarationNode::newEnumValueGeneric( $2, $3 ); }
    28542862        | INLINE type_name
     
    31553163        '|' identifier_or_type_name '(' type_list ')'
    31563164                { $$ = DeclarationNode::newTraitUse( $2, $4 ); }
    3157         | '|' '{' push trait_declaration_list pop '}'
    3158                 { $$ = $4; }
     3165        | '|' '{' trait_declaration_list '}'
     3166                { $$ = $3; }
    31593167        // | '|' '(' push type_parameter_list pop ')' '{' push trait_declaration_list pop '}' '(' type_list ')'
    31603168        //      { SemanticError( yylloc, "Generic data-type assertion is currently unimplemented." ); $$ = nullptr; }
     
    32083216        | forall TRAIT identifier_or_type_name '{' '}'          // alternate
    32093217                { $$ = DeclarationNode::newTrait( $3, $1, nullptr ); }
    3210         | TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}'
     3218        | TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' trait_declaration_list '}'
    32113219                {
    32123220                        SemanticWarning( yylloc, Warning::DeprecTraitSyntax );
    3213                         $$ = DeclarationNode::newTrait( $2, $4, $8 );
    3214                 }
    3215         | forall TRAIT identifier_or_type_name '{' push trait_declaration_list pop '}' // alternate
    3216                 { $$ = DeclarationNode::newTrait( $3, $1, $6 ); }
     3221                        $$ = DeclarationNode::newTrait( $2, $4, $7 );
     3222                }
     3223        | forall TRAIT identifier_or_type_name '{' trait_declaration_list '}' // alternate
     3224                { $$ = DeclarationNode::newTrait( $3, $1, $5 ); }
    32173225        ;
    32183226
    32193227trait_declaration_list:                                                                 // CFA
    32203228        trait_declaration
    3221         | trait_declaration_list pop push trait_declaration
    3222                 { $$ = $1->set_last( $4 ); }
     3229        | trait_declaration_list trait_declaration
     3230                { $$ = $1->set_last( $2 ); }
    32233231        ;
    32243232
     
    32313239        cfa_variable_specifier
    32323240        | cfa_function_specifier
    3233         | cfa_trait_declaring_list pop ',' push identifier_or_type_name
    3234                 { $$ = $1->set_last( $1->cloneType( $5 ) ); }
     3241        | cfa_trait_declaring_list ',' identifier_or_type_name
     3242                { $$ = $1->set_last( $1->cloneType( $3 ) ); }
    32353243        ;
    32363244
    32373245trait_declaring_list:                                                                   // CFA
    3238         type_specifier declarator
     3246                // Cannot declare an aggregate or enumeration in a trait.
     3247        type_specifier_nobody declarator
    32393248                { $$ = $2->addType( $1 ); }
    3240         | trait_declaring_list pop ',' push declarator
    3241                 { $$ = $1->set_last( $1->cloneBaseType( $5 ) ); }
     3249        | trait_declaring_list ',' declarator
     3250                { $$ = $1->set_last( $1->cloneBaseType( $3 ) ); }
     3251        | error
     3252                { SemanticError( yylloc, "Possible cause is declaring an aggregate or enumeration type in a trait." ); $$ = nullptr; }
    32423253        ;
    32433254
  • src/ResolvExpr/CandidateFinder.cpp

    r26d40a1 rd1f5054  
    12811281                                // count one safe conversion for each value that is thrown away
    12821282                                thisCost.incSafe( discardedValues );
     1283
     1284                                // See Aaron Moss, page 47; this reasoning does not hold since implicit conversions
     1285                                // can create the same resolution issue. The C intrinsic interpretations are pruned
     1286                                // immediately for the lowest cost option regardless of result type. Related code in
     1287                                // postvisit (UntypedExpr).
     1288                                // Cast expression costs are updated now to use the general rules.
     1289                                /*
    12831290                                // select first on argument cost, then conversion cost
    12841291                                if ( cand->cost < minExprCost || ( cand->cost == minExprCost && thisCost < minCastCost ) ) {
     
    12891296                                // ambigious case, still output candidates to print in error message
    12901297                                if ( cand->cost == minExprCost && thisCost == minCastCost ) {
     1298                                */
     1299                                cand->cost += thisCost;
     1300                                if (cand->cost < minExprCost) {
     1301                                        minExprCost = cand->cost;
     1302                                        matches.clear();
     1303                                }
     1304                                if (cand->cost == minExprCost) {
    12911305                                        CandidateRef newCand = std::make_shared<Candidate>(
    12921306                                                restructureCast( cand->expr, toType, castExpr->isGenerated ),
    1293                                                 copy( cand->env ), std::move( open ), std::move( need ), cand->cost + thisCost);
     1307                                                copy( cand->env ), std::move( open ), std::move( need ), cand->cost);
    12941308                                        // currently assertions are always resolved immediately so this should have no effect.
    12951309                                        // if this somehow changes in the future (e.g. delayed by indeterminate return type)
  • tests/time.cfa

    r26d40a1 rd1f5054  
    1010// Created On       : Tue Mar 27 17:24:56 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 19 08:06:59 2024
    13 // Update Count     : 75
     12// Last Modified On : Tue Aug 13 09:09:47 2024
     13// Update Count     : 76
    1414//
    1515
     
    1818#include <stdlib.h>                                                                             // putenv
    1919
    20 extern "C" size_t malloc_unfreed() { return 1024; }             // guess at unfreed storage from putenv
     20extern "C" size_t malloc_unfreed() { return 2048; }             // guess at unfreed storage from putenv/tzset
    2121
    2222int main() {
    2323        // Set fixed time location to obtain repeatable output where ever run.
    24         putenv( "TZ=America/Toronto" );                                         // set fixed time zone
     24        putenv( "TZ=America/Toronto" );                                         // pick fixed time zone
    2525        // tzset has the stupidest interface I have ever seen.
    2626        tzset();                                                                                        // set time zone
Note: See TracChangeset for help on using the changeset viewer.