@@ -144,7 +144,6 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
144
144
IGNORED_ATTR(NoObjCBridging)
145
145
IGNORED_ATTR(EmitAssemblyVisionRemarks)
146
146
IGNORED_ATTR(ShowInInterface)
147
- IGNORED_ATTR(SILGenName)
148
147
IGNORED_ATTR(StaticInitializeObjCMetadata)
149
148
IGNORED_ATTR(SynthesizedProtocol)
150
149
IGNORED_ATTR(Testable)
@@ -364,6 +363,8 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
364
363
365
364
void visitStaticExclusiveOnlyAttr (StaticExclusiveOnlyAttr *attr);
366
365
void visitWeakLinkedAttr (WeakLinkedAttr *attr);
366
+
367
+ void visitSILGenNameAttr (SILGenNameAttr *attr);
367
368
};
368
369
369
370
} // end anonymous namespace
@@ -2223,6 +2224,30 @@ void AttributeChecker::visitAvailableAttr(AvailableAttr *attr) {
2223
2224
}
2224
2225
}
2225
2226
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
+
2226
2251
void AttributeChecker::visitCDeclAttr (CDeclAttr *attr) {
2227
2252
// Only top-level func decls are currently supported.
2228
2253
if (D->getDeclContext ()->isTypeContext ())
@@ -2231,6 +2256,12 @@ void AttributeChecker::visitCDeclAttr(CDeclAttr *attr) {
2231
2256
// The name must not be empty.
2232
2257
if (attr->Name .empty ())
2233
2258
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
+ }
2234
2265
}
2235
2266
2236
2267
void AttributeChecker::visitExposeAttr (ExposeAttr *attr) {
@@ -2338,12 +2369,14 @@ void AttributeChecker::visitExternAttr(ExternAttr *attr) {
2338
2369
diagnoseAndRemoveAttr (attr, diag::attr_extern_experimental);
2339
2370
return ;
2340
2371
}
2372
+
2341
2373
// Only top-level func or static func decls are currently supported.
2342
2374
auto *FD = dyn_cast<FuncDecl>(D);
2343
2375
if (!FD || (FD->getDeclContext ()->isTypeContext () && !FD->isStatic ())) {
2344
2376
diagnose (attr->getLocation (), diag::extern_not_at_top_level_func);
2345
2377
}
2346
2378
2379
+
2347
2380
// C name must not be empty.
2348
2381
if (attr->getExternKind () == ExternKind::C) {
2349
2382
StringRef cName = attr->getCName (FD);
@@ -2358,6 +2391,14 @@ void AttributeChecker::visitExternAttr(ExternAttr *attr) {
2358
2391
diagnose (attr->getLocation (), diag::extern_c_maybe_invalid_name, cName)
2359
2392
.fixItInsert (attr->getRParenLoc (), (" , \" " + cName + " \" " ).str ());
2360
2393
}
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
+ }
2361
2402
2362
2403
// Ensure the decl has C compatible interface. Otherwise it produces diagnostics.
2363
2404
if (!isCCompatibleFuncDecl (FD)) {
@@ -2407,6 +2448,13 @@ static bool allowSymbolLinkageMarkers(ASTContext &ctx, Decl *D) {
2407
2448
return false ;
2408
2449
}
2409
2450
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
+
2410
2458
void AttributeChecker::visitUsedAttr (UsedAttr *attr) {
2411
2459
if (!allowSymbolLinkageMarkers (Ctx, D)) {
2412
2460
diagnoseAndRemoveAttr (attr, diag::section_linkage_markers_disabled);
0 commit comments