Ignore:
Timestamp:
Apr 26, 2026, 5:46:08 PM (6 weeks ago)
Author:
Matthew Au-Yeung <mw2auyeu@…>
Branches:
stuck-waitfor-destruct
Parents:
88bb0b4
git-author:
Matthew Au-Yeung <mw2auyeu@…> (04/26/26 17:44:48)
git-committer:
Matthew Au-Yeung <mw2auyeu@…> (04/26/26 17:46:08)
Message:

Set top level autogen cfa_linkonce

  • Remove default static and inline
  • Add pass to autogen functions in lib to have default visibility
  • Add fix for union ctor with array constructor passing pointer to array instead of array itself. Previous changes brought light the compilation error.
  • Note: found compilation trying to invoke union operator with array in cfa
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Validate/Autogen.cpp

    r88bb0b4 rd8a3073  
    352352        replaceAll( assertions, oldToNew );
    353353
     354        bool isTopLevel = ( 0 == functionNesting );
     355        bool isCfaLinkage = getDecl()->linkage.is_mangled;
     356
     357        ast::Storage::Classes storage = ast::Storage::Classes(); // Default no static
     358        ast::Function::Specs funcSpec; // Default no inline
     359        std::vector<ast::ptr<ast::Attribute>> attributes;
     360        if ( !isTopLevel ) {
     361                // Nested: use inline, no linkonce needed for local types.
     362                funcSpec = ast::Function::Specs( ast::Function::Inline );
     363        } else if ( isCfaLinkage ) {
     364                // Top-level CFA type: use linkonce for cross-TU deduplication.
     365                attributes.push_back( new ast::Attribute( "cfa_linkonce" ) );
     366        } else {
     367                // Top-level C type: keep original static inline to avoid
     368                // exposing latent issues in auto-generated code for system types.
     369                storage = ast::Storage::Static;
     370                funcSpec = ast::Function::Specs( ast::Function::Inline );
     371        }
     372
    354373        ast::FunctionDecl * decl = new ast::FunctionDecl(
    355374                // Auto-generated routines use the type declaration's location.
     
    362381                // Only a prototype, no body.
    363382                nullptr,
    364                 // Use static storage if we are at the top level.
    365                 (0 < functionNesting) ? ast::Storage::Classes() : ast::Storage::Static,
     383                storage,
    366384                proto_linkage,
    367                 std::vector<ast::ptr<ast::Attribute>>(),
    368                 // Auto-generated routines are inline to avoid conflicts.
    369                 ast::Function::Specs( ast::Function::Inline ) );
     385                std::move( attributes ),
     386                funcSpec );
    370387        decl->fixUniqueId();
    371388        return decl;
     
    401418                add_qualifiers( dst->type, ast::CV::Qualifiers( ast::CV::Mutex ) );
    402419        }
    403 
    404         ast::FunctionDecl * decl = genProto( "^?{}", { dst }, {} );
    405         // For concurrent types, remove static storage and inline specifier, and add
    406         // cfa_linkonce attribute so the destructor has linkonce semantics.
    407         // This is required to share the same function pointer across TUs.
    408         if ( isConcurrentType() ) {
    409                 auto mut = ast::mutate( decl );
    410                 mut->storage = ast::Storage::Classes();
    411                 mut->funcSpec = ast::Function::Specs();
    412                 mut->attributes.push_back( new ast::Attribute( "cfa_linkonce" ) );
    413         }
    414         return decl;
     420        return genProto( "^?{}", { dst }, {} );
    415421}
    416422
     
    697703                        new ast::AddressExpr( location,
    698704                                new ast::VariableExpr( location, dstParam ) ),
    699                         new ast::AddressExpr( location,
    700                                 new ast::VariableExpr( location, srcParam ) ),
     705                        // For array types, the parameter decays to a pointer, so the
     706                        // variable already points to the data. For other types, take &src.
     707                        dynamic_cast<const ast::ArrayType *>( srcParam->type.get() )
     708                                ? (ast::Expr *)new ast::CastExpr( location,
     709                                        new ast::VariableExpr( location, srcParam ),
     710                                        new ast::PointerType( new ast::VoidType() ) )
     711                                : (ast::Expr *)new ast::AddressExpr( location,
     712                                        new ast::VariableExpr( location, srcParam ) ),
    701713                        new ast::SizeofExpr( location, srcParam->type ),
    702714                } ) );
Note: See TracChangeset for help on using the changeset viewer.