Changeset 13481af0 for src


Ignore:
Timestamp:
Jul 2, 2026, 5:07:05 PM (2 days ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
7886a92f
Parents:
16d862d
Message:

remove addDataSectionAttribute hack and handle dynamic initialization of const definitions by removing the const after resolution

Location:
src/InitTweak
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixGlobalInit.cpp

    r16d862d r13481af0  
    1010// Created On       : Mon May 04 15:14:56 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Dec 13 23:41:10 2019
    13 // Update Count     : 19
     12// Last Modified On : Thu Jul  2 16:39:52 2026
     13// Update Count     : 35
    1414//
    1515
    1616#include "FixGlobalInit.hpp"
    1717
     18#include <set>
    1819#include <cassert>                 // for assert
    1920#include <stddef.h>                // for NULL
     
    4041        void previsit(const ast::TypeDecl *) { visit_children = false; }
    4142
     43        bool pass = false;
    4244        std::list< ast::ptr<ast::Stmt> > initStmts;
    4345        std::list< ast::ptr<ast::Stmt> > destroyStmts;
     46        std::set< std::string > constDeclsMnames;
    4447};
    4548
     
    4750        auto mutDecl = mutate(objDecl);
    4851        assertf(mutDecl == objDecl, "Global object decl must be unique");
    49         auto ctorInit = objDecl->init.as<ast::ConstructorInit>();
    50         if ( nullptr == ctorInit ) return;
     52        if ( ! pass ) {                                                                         // pass 1
     53                auto ctorInit = objDecl->init.as<ast::ConstructorInit>();
     54                if ( nullptr == ctorInit ) return;
    5155
    52         // a decision should have been made by the resolver, so ctor and init are not both non-NULL
    53         assert( !ctorInit->ctor || !ctorInit->init );
     56                // a decision should have been made by the resolver, so ctor and init are not both non-NULL
     57                assert( !ctorInit->ctor || !ctorInit->init );
    5458
    55         const ast::Stmt * dtor = ctorInit->dtor;
    56         if ( dtor && !isIntrinsicSingleArgCallStmt( dtor ) ) {
    57                 // don't need to call intrinsic dtor, because it does nothing, but
    58                 // non-intrinsic dtors must be called
    59                 destroyStmts.push_front( dtor );
    60         } // if
    61         if ( const ast::Stmt * ctor = ctorInit->ctor ) {
    62                 addDataSectionAttribute(mutDecl);
    63                 initStmts.push_back( ctor );
    64                 mutDecl->init = nullptr;
    65         } else if ( const ast::Init * init = ctorInit->init ) {
    66                 mutDecl->init = init;
    67         } else {
    68                 // no constructor and no initializer, which is okay
    69                 mutDecl->init = nullptr;
     59                const ast::Stmt * dtor = ctorInit->dtor;
     60                if ( dtor && !isIntrinsicSingleArgCallStmt( dtor ) ) {
     61                        // don't need to call intrinsic dtor, because it does nothing, but
     62                        // non-intrinsic dtors must be called
     63                        destroyStmts.push_front( dtor );
     64                } // if
     65                if ( const ast::Stmt * ctor = ctorInit->ctor ) {
     66                        if ( mutDecl->type->is_const() ) {
     67                                // Store names of all declarations with const qualifier and initializer for second pass.
     68                                constDeclsMnames.emplace( mutDecl->mangleName );
     69                        }
     70                        initStmts.push_back( ctor );
     71                        mutDecl->init = nullptr;
     72                } else if ( const ast::Init * init = ctorInit->init ) {
     73                        mutDecl->init = init;
     74                } else {
     75                        // no constructor and no initializer, which is okay
     76                        mutDecl->init = nullptr;
     77                }
     78        } else {                                                                                // pass 2
     79                // Remove const qualifier from matching names, covering all forward declaration(s) and definition.
     80                if ( constDeclsMnames.find( objDecl->mangleName ) != constDeclsMnames.end() ) {
     81                        ast::Type * fred = const_cast<ast::Type *>(mutDecl->get_type());
     82                        fred->set_const( false );
     83                } // if
    7084        }
    7185}
     
    7589void fixGlobalInit(ast::TranslationUnit & translationUnit, bool inLibrary) {
    7690        ast::Pass<GlobalFixer> fixer;
    77         accept_all(translationUnit, fixer);
     91
     92        // First pass fixes global initialization.
     93        accept_all( translationUnit, fixer );
    7894
    7995        // Say these magic declarations come at the end of the file.
     
    103119                translationUnit.decls.emplace_back(destroyFunction);
    104120        } // if
     121
     122        fixer.core.pass = ! fixer.core.pass;
     123        // Second pass, removes const qualifiers so declarations appear in mutable .data section.
     124        // Note, the resolver has already checked for const-ness, so C only has to get the initialization correct.
     125        accept_all(translationUnit, fixer);
    105126}
    106127
  • src/InitTweak/FixInit.cpp

    r16d862d r13481af0  
    816816        if ( const ast::Stmt * ctor = ctorInit->ctor ) {
    817817                if ( objDecl->storage.is_static ) {
    818                         addDataSectionAttribute(objDecl);
     818                        // Remove const qualifier from definition and there can be no forward declarations.
     819                        if ( objDecl->type->is_const() ) {
     820                                ast::Type * fred = const_cast<ast::Type *>(objDecl->get_type());
     821                                fred->set_const( false );
     822                        }
    819823                        // originally wanted to take advantage of gcc nested functions, but
    820824                        // we get memory errors with this approach. To remedy this, the static
  • src/InitTweak/InitTweak.cpp

    r16d862d r13481af0  
    99// Author           : Rob Schluntz
    1010// Created On       : Fri May 13 11:26:36 2016
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Sep 22  9:50:00 2022
    13 // Update Count     : 21
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Jul  2 16:47:11 2026
     13// Update Count     : 44
    1414//
    1515
     
    428428}
    429429
    430 #if defined( __x86_64 ) || defined( __i386 ) // assembler comment to prevent assembler warning message
    431         #define ASM_COMMENT "#"
    432 #else // defined( __ARM_ARCH )
    433         #define ASM_COMMENT "//"
    434 #endif
    435 static const char * const data_section =  ".data" ASM_COMMENT;
    436 static const char * const tlsd_section = ".tdata" ASM_COMMENT;
    437 
    438 void addDataSectionAttribute( ast::ObjectDecl * objDecl ) {
    439         const bool is_tls = objDecl->storage.is_threadlocal_any();
    440         const char * section = is_tls ? tlsd_section : data_section;
    441         objDecl->attributes.push_back(new ast::Attribute("section", {
    442                 ast::ConstantExpr::from_string(objDecl->location, section)
    443         }));
    444 }
    445 
    446430InitExpander::InitExpander( const ast::Init * init )
    447431: expander( new InitImpl{ init } ), crnt(), indices() {}
  • src/InitTweak/InitTweak.hpp

    r16d862d r13481af0  
    99// Author           : Rob Schluntz
    1010// Created On       : Fri May 13 11:26:36 2016
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Sep 22  9:21:00 2022
    13 // Update Count     : 9
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Jul  2 16:45:44 2026
     13// Update Count     : 12
    1414//
    1515
     
    6969bool isConstExpr( const ast::Init * init );
    7070
    71 /// Modifies objDecl to have:
    72 ///    __attribute__((section (".data#")))
    73 /// which makes gcc put the declared variable in the data section,
    74 /// which is helpful for global constants on newer gcc versions,
    75 /// so that CFA's generated initialization won't segfault when writing it via a const cast.
    76 /// The trailing # is an injected assembly comment, to suppress the "a" in
    77 ///    .section .data,"a"
    78 ///    .section .data#,"a"
    79 /// to avoid assembler warning "ignoring changed section attributes for .data"
    80 void addDataSectionAttribute( ast::ObjectDecl * objDecl );
    81 
    8271class InitExpander final {
    8372public:
Note: See TracChangeset for help on using the changeset viewer.