Changeset 13481af0
- Timestamp:
- Jul 2, 2026, 5:07:05 PM (2 days ago)
- Branches:
- master
- Children:
- 7886a92f
- Parents:
- 16d862d
- Location:
- src/InitTweak
- Files:
-
- 4 edited
-
FixGlobalInit.cpp (modified) (5 diffs)
-
FixInit.cpp (modified) (1 diff)
-
InitTweak.cpp (modified) (2 diffs)
-
InitTweak.hpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixGlobalInit.cpp
r16d862d r13481af0 10 10 // Created On : Mon May 04 15:14:56 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Dec 13 23:41:10 201913 // Update Count : 1912 // Last Modified On : Thu Jul 2 16:39:52 2026 13 // Update Count : 35 14 14 // 15 15 16 16 #include "FixGlobalInit.hpp" 17 17 18 #include <set> 18 19 #include <cassert> // for assert 19 20 #include <stddef.h> // for NULL … … 40 41 void previsit(const ast::TypeDecl *) { visit_children = false; } 41 42 43 bool pass = false; 42 44 std::list< ast::ptr<ast::Stmt> > initStmts; 43 45 std::list< ast::ptr<ast::Stmt> > destroyStmts; 46 std::set< std::string > constDeclsMnames; 44 47 }; 45 48 … … 47 50 auto mutDecl = mutate(objDecl); 48 51 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; 51 55 52 // a decision should have been made by the resolver, so ctor and init are not both non-NULL53 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 ); 54 58 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 70 84 } 71 85 } … … 75 89 void fixGlobalInit(ast::TranslationUnit & translationUnit, bool inLibrary) { 76 90 ast::Pass<GlobalFixer> fixer; 77 accept_all(translationUnit, fixer); 91 92 // First pass fixes global initialization. 93 accept_all( translationUnit, fixer ); 78 94 79 95 // Say these magic declarations come at the end of the file. … … 103 119 translationUnit.decls.emplace_back(destroyFunction); 104 120 } // 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); 105 126 } 106 127 -
src/InitTweak/FixInit.cpp
r16d862d r13481af0 816 816 if ( const ast::Stmt * ctor = ctorInit->ctor ) { 817 817 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 } 819 823 // originally wanted to take advantage of gcc nested functions, but 820 824 // we get memory errors with this approach. To remedy this, the static -
src/InitTweak/InitTweak.cpp
r16d862d r13481af0 9 9 // Author : Rob Schluntz 10 10 // Created On : Fri May 13 11:26:36 2016 11 // Last Modified By : Andrew Beach12 // Last Modified On : Wed Sep 22 9:50:00 202213 // Update Count : 2111 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 2 16:47:11 2026 13 // Update Count : 44 14 14 // 15 15 … … 428 428 } 429 429 430 #if defined( __x86_64 ) || defined( __i386 ) // assembler comment to prevent assembler warning message431 #define ASM_COMMENT "#"432 #else // defined( __ARM_ARCH )433 #define ASM_COMMENT "//"434 #endif435 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 446 430 InitExpander::InitExpander( const ast::Init * init ) 447 431 : expander( new InitImpl{ init } ), crnt(), indices() {} -
src/InitTweak/InitTweak.hpp
r16d862d r13481af0 9 9 // Author : Rob Schluntz 10 10 // Created On : Fri May 13 11:26:36 2016 11 // Last Modified By : Andrew Beach12 // Last Modified On : Wed Sep 22 9:21:00 202213 // Update Count : 911 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 2 16:45:44 2026 13 // Update Count : 12 14 14 // 15 15 … … 69 69 bool isConstExpr( const ast::Init * init ); 70 70 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" in77 /// .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 82 71 class InitExpander final { 83 72 public:
Note:
See TracChangeset
for help on using the changeset viewer.