Changeset 8da7421f


Ignore:
Timestamp:
Oct 20, 2020, 12:35:25 PM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
3aec25f
Parents:
5afb49a (diff), d5631b3 (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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
17 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Expr.cpp

    r5afb49a r8da7421f  
    102102        }
    103103        return ret;
     104}
     105
     106// --- VariableExpr
     107
     108VariableExpr::VariableExpr( const CodeLocation & loc )
     109: Expr( loc ), var( nullptr ) {}
     110
     111VariableExpr::VariableExpr( const CodeLocation & loc, const DeclWithType * v )
     112: Expr( loc ), var( v ) {
     113        assert( var );
     114        assert( var->get_type() );
     115        result = shallowCopy( var->get_type() );
     116}
     117
     118bool VariableExpr::get_lvalue() const {
     119        // It isn't always an lvalue, but it is never an rvalue.
     120        return true;
     121}
     122
     123VariableExpr * VariableExpr::functionPointer(
     124                const CodeLocation & loc, const FunctionDecl * decl ) {
     125        // wrap usually-determined result type in a pointer
     126        VariableExpr * funcExpr = new VariableExpr{ loc, decl };
     127        funcExpr->result = new PointerType{ funcExpr->result };
     128        return funcExpr;
    104129}
    105130
     
    238263}
    239264
    240 // --- VariableExpr
    241 
    242 VariableExpr::VariableExpr( const CodeLocation & loc )
    243 : Expr( loc ), var( nullptr ) {}
    244 
    245 VariableExpr::VariableExpr( const CodeLocation & loc, const DeclWithType * v )
    246 : Expr( loc ), var( v ) {
    247         assert( var );
    248         assert( var->get_type() );
    249         result = shallowCopy( var->get_type() );
    250 }
    251 
    252 bool VariableExpr::get_lvalue() const {
    253         // It isn't always an lvalue, but it is never an rvalue.
    254         return true;
    255 }
    256 
    257 VariableExpr * VariableExpr::functionPointer(
    258                 const CodeLocation & loc, const FunctionDecl * decl ) {
    259         // wrap usually-determined result type in a pointer
    260         VariableExpr * funcExpr = new VariableExpr{ loc, decl };
    261         funcExpr->result = new PointerType{ funcExpr->result };
    262         return funcExpr;
    263 }
    264 
    265265// --- ConstantExpr
    266266
  • src/AST/Expr.hpp

    r5afb49a r8da7421f  
    250250};
    251251
     252/// A reference to a named variable.
     253class VariableExpr final : public Expr {
     254public:
     255        readonly<DeclWithType> var;
     256
     257        VariableExpr( const CodeLocation & loc );
     258        VariableExpr( const CodeLocation & loc, const DeclWithType * v );
     259
     260        bool get_lvalue() const final;
     261
     262        /// generates a function pointer for a given function
     263        static VariableExpr * functionPointer( const CodeLocation & loc, const FunctionDecl * decl );
     264
     265        const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
     266private:
     267        VariableExpr * clone() const override { return new VariableExpr{ *this }; }
     268        MUTATE_FRIEND
     269};
     270
    252271/// Address-of expression `&e`
    253272class AddressExpr final : public Expr {
     
    390409        friend class ::ConverterOldToNew;
    391410        friend class ::ConverterNewToOld;
    392 };
    393 
    394 /// A reference to a named variable.
    395 class VariableExpr final : public Expr {
    396 public:
    397         readonly<DeclWithType> var;
    398 
    399         VariableExpr( const CodeLocation & loc );
    400         VariableExpr( const CodeLocation & loc, const DeclWithType * v );
    401 
    402         bool get_lvalue() const final;
    403 
    404         /// generates a function pointer for a given function
    405         static VariableExpr * functionPointer( const CodeLocation & loc, const FunctionDecl * decl );
    406 
    407         const Expr * accept( Visitor & v ) const override { return v.visit( this ); }
    408 private:
    409         VariableExpr * clone() const override { return new VariableExpr{ *this }; }
    410         MUTATE_FRIEND
    411411};
    412412
  • src/InitTweak/FixGlobalInit.cc

    r5afb49a r8da7421f  
    112112                        } // if
    113113                        if ( Statement * ctor = ctorInit->ctor ) {
    114                                 // Translation 1: Add this attribute on the global declaration:
    115                                 //    __attribute__((section (".data#")))
    116                                 // which makes gcc put the global in the data section,
    117                                 // so that the global is writeable (via a const cast) in the init function.
    118                                 // The trailing # is an injected assembly comment, to suppress the "a" in
    119                                 //    .section .data,"a"
    120                                 //    .section .data#,"a"
    121                                 // to avoid assembler warning "ignoring changed section attributes for .data"
    122                                 Type *strLitT = new PointerType( Type::Qualifiers( ),
    123                                         new BasicType( Type::Qualifiers( ), BasicType::Char ) );
    124                                 std::list< Expression * > attr_params;
    125                                 attr_params.push_back(
    126                                         new ConstantExpr( Constant( strLitT, "\".data#\"", std::nullopt ) ) );
    127                                 objDecl->attributes.push_back(new Attribute("section", attr_params));
    128                                 // Translation 2: Move the initizliation off the global declaration,
    129                                 // into the startup function.
     114                                addDataSectonAttribute( objDecl );
    130115                                initStatements.push_back( ctor );
    131116                                objDecl->init = nullptr;
  • src/InitTweak/FixInit.cc

    r5afb49a r8da7421f  
    802802                                if ( Statement * ctor = ctorInit->get_ctor() ) {
    803803                                        if ( objDecl->get_storageClasses().is_static ) {
     804
     805                                                // The ojbect needs to go in the data section, regardless of dtor complexity below.
     806                                                // The attribute works, and is meant to apply, both for leaving the static local alone,
     807                                                // and for hoisting it out as a static global.
     808                                                addDataSectonAttribute( objDecl );
     809
    804810                                                // originally wanted to take advantage of gcc nested functions, but
    805811                                                // we get memory errors with this approach. To remedy this, the static
  • src/InitTweak/InitTweak.cc

    r5afb49a r8da7421f  
    10551055                return isCopyFunction( decl, "?{}" );
    10561056        }
     1057
     1058        void addDataSectonAttribute( ObjectDecl * objDecl ) {
     1059                Type *strLitT = new PointerType( Type::Qualifiers( ),
     1060                        new BasicType( Type::Qualifiers( ), BasicType::Char ) );
     1061                std::list< Expression * > attr_params;
     1062                attr_params.push_back(
     1063                        new ConstantExpr( Constant( strLitT, "\".data#\"", std::nullopt ) ) );
     1064                objDecl->attributes.push_back(new Attribute("section", attr_params));
     1065        }
     1066
    10571067}
  • src/InitTweak/InitTweak.h

    r5afb49a r8da7421f  
    103103        bool isConstExpr( Initializer * init );
    104104
     105        /// Modifies objDecl to have:
     106        ///    __attribute__((section (".data#")))
     107        /// which makes gcc put the declared variable in the data section,
     108        /// which is helpful for global constants on newer gcc versions,
     109        /// so that CFA's generated initialization won't segfault when writing it via a const cast.
     110        /// The trailing # is an injected assembly comment, to suppress the "a" in
     111        ///    .section .data,"a"
     112        ///    .section .data#,"a"
     113        /// to avoid assembler warning "ignoring changed section attributes for .data"
     114        void addDataSectonAttribute( ObjectDecl * objDecl );
     115
    105116        class InitExpander_old {
    106117        public:
  • src/SynTree/Expression.h

    r5afb49a r8da7421f  
    163163};
    164164
     165/// VariableExpr represents an expression that simply refers to the value of a named variable.
     166/// Does not take ownership of var.
     167class VariableExpr : public Expression {
     168  public:
     169        DeclarationWithType * var;
     170
     171        VariableExpr();
     172        VariableExpr( DeclarationWithType * var );
     173        VariableExpr( const VariableExpr & other );
     174        virtual ~VariableExpr();
     175
     176        bool get_lvalue() const final;
     177
     178        DeclarationWithType * get_var() const { return var; }
     179        void set_var( DeclarationWithType * newValue ) { var = newValue; }
     180
     181        static VariableExpr * functionPointer( FunctionDecl * decl );
     182
     183        virtual VariableExpr * clone() const override { return new VariableExpr( * this ); }
     184        virtual void accept( Visitor & v ) override { v.visit( this ); }
     185        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     186        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     187        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     188};
     189
    165190// The following classes are used to represent expression types that cannot be converted into
    166191// function-call format.
     
    329354};
    330355
    331 /// VariableExpr represents an expression that simply refers to the value of a named variable.
    332 /// Does not take ownership of var.
    333 class VariableExpr : public Expression {
    334   public:
    335         DeclarationWithType * var;
    336 
    337         VariableExpr();
    338         VariableExpr( DeclarationWithType * var );
    339         VariableExpr( const VariableExpr & other );
    340         virtual ~VariableExpr();
    341 
    342         bool get_lvalue() const final;
    343 
    344         DeclarationWithType * get_var() const { return var; }
    345         void set_var( DeclarationWithType * newValue ) { var = newValue; }
    346 
    347         static VariableExpr * functionPointer( FunctionDecl * decl );
    348 
    349         virtual VariableExpr * clone() const override { return new VariableExpr( * this ); }
    350         virtual void accept( Visitor & v ) override { v.visit( this ); }
    351         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    352         virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    353         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    354 };
    355 
    356356/// ConstantExpr represents an expression that simply refers to the value of a constant
    357357class ConstantExpr : public Expression {
  • tests/.expect/const-init.txt

    r5afb49a r8da7421f  
    1 done
     1almost done
     2dtor
  • tests/complex.cfa

    r5afb49a r8da7421f  
    1414//
    1515
    16 #include <stdio.h>
    1716#include <complex.h>
    1817#ifdef __CFA__
  • tests/const-init.cfa

    r5afb49a r8da7421f  
    1616/*
    1717
    18 This test shows non-crashing of generated code for constants with interesting initizers.
     18These tests show non-crashing of generated code for constants with interesting initializers.
    1919The potential for these to crash is compiler dependent.
    2020
    2121There are two cases:
    22 1. static constants in one compilation unit (tested here)
     221. static constants in one compilation unit (tested here, in a few sub-cases)
    23232. extern constants across compilation units (tested by libcfa being loadable, specifically
    24    the constant declarations in libcfa/src/limits.cfa, which almost every test exercises,
     24   the constant definitions in libcfa/src/limits.cfa, which almost every test exercises,
    2525   including "hello;" but notably, the "limits" test does not exercise it because that test
    2626   is compile-only)
     
    3737GCC-10 on Ubuntu 20.04    Has crashed      Has crashed
    3838
    39 For this test case to fail, with most other tests passing, would be a situation only ever
     39For this test to fail, with most other tests passing, would be a situation only ever
    4040observed with GCC-8.
    4141
    4242*/
    4343
     44// initailized by generated function, called before main
    4445static const char foo = -1;
    4546
     47struct thing{};
     48void ^?{}( thing & ) { printf("dtor\n"); }
     49
    4650int main() {
    47     printf("done\n");
     51    // foo is already initialized
     52
     53    // no dtor => stays a (static) local, initialized here
     54    static const char bar = -1;
     55
     56    // has dtor => becomes a global, ctor called here, dtor called at exit
     57    static const thing it;
     58
     59    printf("almost done\n");
    4860}
  • tests/exceptions/cancel/coroutine.cfa

    r5afb49a r8da7421f  
    11// Try cancelling a coroutine.
    22
    3 #include <stdio.h>
    43#include <coroutine.hfa>
    54#include <exception.hfa>
  • tests/exceptions/conditional.cfa

    r5afb49a r8da7421f  
    55
    66#include <exception.hfa>
    7 #include <stdio.h>
    87
    98VTABLE_DECLARATION(num_error)(
  • tests/exceptions/except-io.hfa

    r5afb49a r8da7421f  
    11// Common tools for the exception tests.
    2 
    3 #include <stdio.h>
    42
    53// Echo when a destructor is run and an area/block is left.
  • tests/exceptions/trash.cfa

    r5afb49a r8da7421f  
    22
    33#include <exception.hfa>
    4 #include <stdio.h>
    54
    65TRIVIAL_EXCEPTION(yin);
  • tests/global-monomorph.cfa

    r5afb49a r8da7421f  
    1 // Crea
    2 
    3 #include <stdlib.hfa>
    4 #include <stdio.h>
     1// Create monomorphic instances of polymorphic types at global scope.
    52
    63forall(dtype T)
  • tests/poly-d-cycle.cfa

    r5afb49a r8da7421f  
    11// Check that a cycle of polymorphic dtype structures can be instancated.
    2 
    3 #include <stdio.h>
    42
    53forall(dtype T)
  • tests/poly-o-cycle.cfa

    r5afb49a r8da7421f  
    11// Check that a cycle of polymorphic otype structures can be instancated.
    2 
    3 #include <stdio.h>
    42
    53forall(otype T)
Note: See TracChangeset for help on using the changeset viewer.