@@ -144,7 +144,6 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
144144 IGNORED_ATTR(NoObjCBridging)
145145 IGNORED_ATTR(EmitAssemblyVisionRemarks)
146146 IGNORED_ATTR(ShowInInterface)
147- IGNORED_ATTR(SILGenName)
148147 IGNORED_ATTR(StaticInitializeObjCMetadata)
149148 IGNORED_ATTR(SynthesizedProtocol)
150149 IGNORED_ATTR(Testable)
@@ -364,6 +363,8 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
364363
365364 void visitStaticExclusiveOnlyAttr (StaticExclusiveOnlyAttr *attr);
366365 void visitWeakLinkedAttr (WeakLinkedAttr *attr);
366+
367+ void visitSILGenNameAttr (SILGenNameAttr *attr);
367368};
368369
369370} // end anonymous namespace
@@ -2223,6 +2224,30 @@ void AttributeChecker::visitAvailableAttr(AvailableAttr *attr) {
22232224 }
22242225}
22252226
2227+ static bool canDeclareSymbolName (StringRef symbol, ModuleDecl *fromModule) {
2228+ // The Swift standard library needs to be able to define reserved symbols.
2229+ if (fromModule->isStdlibModule ()
2230+ || fromModule->getName () == fromModule->getASTContext ().Id_Concurrency
2231+ || fromModule->getName () == fromModule->getASTContext ().Id_Distributed ) {
2232+ return true ;
2233+ }
2234+
2235+ // Swift runtime functions are a private contract between the compiler and
2236+ // runtime, and attempting to access them directly without going through
2237+ // builtins or proper language features breaks the compiler in various hard
2238+ // to predict ways. Warn when code attempts to do so; hopefully we can
2239+ // promote this to an error after a while.
2240+
2241+ return llvm::StringSwitch<bool >(symbol)
2242+ #define FUNCTION (_, Name, ...) \
2243+ .Case (#Name, false ) \
2244+ .Case (" _" #Name, false ) \
2245+ .Case (#Name " _" , false ) \
2246+ .Case (" _" #Name " _" , false )
2247+ #include " swift/Runtime/RuntimeFunctions.def"
2248+ .Default (true );
2249+ }
2250+
22262251void AttributeChecker::visitCDeclAttr (CDeclAttr *attr) {
22272252 // Only top-level func decls are currently supported.
22282253 if (D->getDeclContext ()->isTypeContext ())
@@ -2231,6 +2256,12 @@ void AttributeChecker::visitCDeclAttr(CDeclAttr *attr) {
22312256 // The name must not be empty.
22322257 if (attr->Name .empty ())
22332258 diagnose (attr->getLocation (), diag::cdecl_empty_name);
2259+
2260+ // The standard library can use @_cdecl to implement runtime functions.
2261+ if (!canDeclareSymbolName (attr->Name , D->getModuleContext ())) {
2262+ diagnose (attr->getLocation (), diag::reserved_runtime_symbol_name,
2263+ attr->Name );
2264+ }
22342265}
22352266
22362267void AttributeChecker::visitExposeAttr (ExposeAttr *attr) {
@@ -2338,12 +2369,14 @@ void AttributeChecker::visitExternAttr(ExternAttr *attr) {
23382369 diagnoseAndRemoveAttr (attr, diag::attr_extern_experimental);
23392370 return ;
23402371 }
2372+
23412373 // Only top-level func or static func decls are currently supported.
23422374 auto *FD = dyn_cast<FuncDecl>(D);
23432375 if (!FD || (FD->getDeclContext ()->isTypeContext () && !FD->isStatic ())) {
23442376 diagnose (attr->getLocation (), diag::extern_not_at_top_level_func);
23452377 }
23462378
2379+
23472380 // C name must not be empty.
23482381 if (attr->getExternKind () == ExternKind::C) {
23492382 StringRef cName = attr->getCName (FD);
@@ -2358,6 +2391,14 @@ void AttributeChecker::visitExternAttr(ExternAttr *attr) {
23582391 diagnose (attr->getLocation (), diag::extern_c_maybe_invalid_name, cName)
23592392 .fixItInsert (attr->getRParenLoc (), (" , \" " + cName + " \" " ).str ());
23602393 }
2394+
2395+ // Diagnose reserved symbol names.
2396+ // The standard library can't use normal C interop so needs extern(c)
2397+ // for access to C standard library and ObjC/Swift runtime functions.
2398+ if (!canDeclareSymbolName (cName, D->getModuleContext ())) {
2399+ diagnose (attr->getLocation (), diag::reserved_runtime_symbol_name,
2400+ cName);
2401+ }
23612402
23622403 // Ensure the decl has C compatible interface. Otherwise it produces diagnostics.
23632404 if (!isCCompatibleFuncDecl (FD)) {
@@ -2407,6 +2448,13 @@ static bool allowSymbolLinkageMarkers(ASTContext &ctx, Decl *D) {
24072448 return false ;
24082449}
24092450
2451+ void AttributeChecker::visitSILGenNameAttr (SILGenNameAttr *A) {
2452+ if (!canDeclareSymbolName (A->Name , D->getModuleContext ())) {
2453+ diagnose (A->getLocation (), diag::reserved_runtime_symbol_name,
2454+ A->Name );
2455+ }
2456+ }
2457+
24102458void AttributeChecker::visitUsedAttr (UsedAttr *attr) {
24112459 if (!allowSymbolLinkageMarkers (Ctx, D)) {
24122460 diagnoseAndRemoveAttr (attr, diag::section_linkage_markers_disabled);
0 commit comments