Skip to content

Commit 8789871

Browse files
committed
Diagnose @safe @unsafe when used together
Fixes rdar://147943857.
1 parent d86f41a commit 8789871

File tree

3 files changed

+16
-2
lines changed

3 files changed

+16
-2
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8233,7 +8233,7 @@ NOTE(sending_function_result_with_sending_param_note, none,
82338233
())
82348234

82358235
//------------------------------------------------------------------------------
8236-
// MARK: Strict Safety Diagnostics
8236+
// MARK: Strict Memory Safety Diagnostics
82378237
//------------------------------------------------------------------------------
82388238
NOTE(note_reference_to_unsafe_decl,none,
82398239
"%select{reference|call}0 to unsafe %kind1",
@@ -8272,6 +8272,9 @@ NOTE(decl_storage_mark_safe,none,
82728272
"add '@safe' if this type encapsulates the unsafe storage in "
82738273
"a safe interface", ())
82748274

8275+
ERROR(safe_and_unsafe_attr,none,
8276+
"%kindbase0 cannot be both @safe and @unsafe", (const Decl *))
8277+
82758278
GROUPED_WARNING(unsafe_superclass,StrictMemorySafety,none,
82768279
"%kindbase0 has superclass involving unsafe type %1",
82778280
(const ValueDecl *, Type))

lib/Sema/TypeCheckAttr.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,6 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
192192
IGNORED_ATTR(AllowFeatureSuppression)
193193
IGNORED_ATTR(PreInverseGenerics)
194194
IGNORED_ATTR(Safe)
195-
IGNORED_ATTR(Unsafe)
196195
#undef IGNORED_ATTR
197196

198197
void visitABIAttr(ABIAttr *attr) {
@@ -445,6 +444,7 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
445444
void visitLifetimeAttr(LifetimeAttr *attr);
446445
void visitAddressableSelfAttr(AddressableSelfAttr *attr);
447446
void visitAddressableForDependenciesAttr(AddressableForDependenciesAttr *attr);
447+
void visitUnsafeAttr(UnsafeAttr *attr);
448448
};
449449

450450
} // end anonymous namespace
@@ -8140,6 +8140,14 @@ AttributeChecker::visitAddressableForDependenciesAttr(
81408140
}
81418141
}
81428142

8143+
void AttributeChecker::visitUnsafeAttr(UnsafeAttr *attr) {
8144+
if (auto safeAttr = D->getAttrs().getAttribute<SafeAttr>()) {
8145+
D->diagnose(diag::safe_and_unsafe_attr, D)
8146+
.highlight(attr->getRange())
8147+
.highlight(safeAttr->getRange());
8148+
}
8149+
}
8150+
81438151
namespace {
81448152

81458153
class ClosureAttributeChecker

test/Unsafe/safe.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,3 +268,6 @@ struct UnsafeWrapTest {
268268
}
269269
}
270270
}
271+
272+
@safe @unsafe
273+
struct ConfusedStruct { } // expected-error{{struct 'ConfusedStruct' cannot be both @safe and @unsafe}}

0 commit comments

Comments
 (0)