Changeset d8a3073 for src/Validate/Autogen.cpp
- Timestamp:
- Apr 26, 2026, 5:46:08 PM (6 weeks ago)
- 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)
- File:
-
- 1 edited
-
src/Validate/Autogen.cpp (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Validate/Autogen.cpp
r88bb0b4 rd8a3073 352 352 replaceAll( assertions, oldToNew ); 353 353 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 354 373 ast::FunctionDecl * decl = new ast::FunctionDecl( 355 374 // Auto-generated routines use the type declaration's location. … … 362 381 // Only a prototype, no body. 363 382 nullptr, 364 // Use static storage if we are at the top level. 365 (0 < functionNesting) ? ast::Storage::Classes() : ast::Storage::Static, 383 storage, 366 384 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 ); 370 387 decl->fixUniqueId(); 371 388 return decl; … … 401 418 add_qualifiers( dst->type, ast::CV::Qualifiers( ast::CV::Mutex ) ); 402 419 } 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 }, {} ); 415 421 } 416 422 … … 697 703 new ast::AddressExpr( location, 698 704 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 ) ), 701 713 new ast::SizeofExpr( location, srcParam->type ), 702 714 } ) );
Note:
See TracChangeset
for help on using the changeset viewer.