Files
swift-mirror/include/swift/AST/SemanticAttrs.def
Joe Groff 3d5285be6f Arrange for closure bodies promoted by AllocBoxToStack to have their originals removed by MoveOnlyChecker.
This is an improvement of #67031 which avoids deleting the closure function
body during AllocBoxToStack, which still breaks pass invariants by modifying
functions other than the currently-analyzed function. As a function pass,
AllocBoxToStack also doesn't really know with certainty whether the original
closure function is unused after stack promotion or not. We still want to
eliminate the original when it may contain invalid SIL for move-only values
that rely on the escape analysis for correct semantics, so rather than mark the
original function to be *ignored* during move-only checking, mark it to be
*deleted* by move-only checking if the function is in fact unused at that
point.

If the marked function is still used, we let it pass through move-only
checking normally, which may cause redundant diagnostics but is the right
thing to do since code is still potentially using the closure with escaping
semantics. We should rearrange things to make this situation impossible in
the future.

rdar://110675352
2023-07-10 15:18:16 -07:00

154 lines
7.7 KiB
C++

//===--- Semantics.def - Semantics Attribute Definitions -------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This macro is used to map the global definition name of a semantic
/// attribute to its raw value.
/// NAME: the global name used in the compiler
/// C_STR: the raw value used in swift
///
/// SEMANTICS_ATTR(NAME, C_STR)
///
//===----------------------------------------------------------------------===//
#ifndef SEMANTICS_ATTR
#error SEMANTICS_ATTR not defined.
#endif
SEMANTICS_ATTR(STRING_EQUALS, "string.equals")
SEMANTICS_ATTR(STRING_MAKE_UTF8, "string.makeUTF8")
SEMANTICS_ATTR(STRING_GET_UTF8_CSTRING, "string.getUTF8CString")
SEMANTICS_ATTR(STRING_ESCAPE_PERCENT_GET, "string.escapePercent.get")
SEMANTICS_ATTR(STRING_CONCAT, "string.concat")
SEMANTICS_ATTR(STRING_APPEND, "string.append")
SEMANTICS_ATTR(STRING_INIT_EMPTY, "string.init_empty")
SEMANTICS_ATTR(STRING_INIT_EMPTY_WITH_CAPACITY, "string.init_empty_with_capacity")
SEMANTICS_ATTR(STRING_PLUS_EQUALS, "string.plusequals")
SEMANTICS_ATTR(FIND_STRING_SWITCH_CASE, "findStringSwitchCase")
SEMANTICS_ATTR(FIND_STRING_SWITCH_CASE_WITH_CACHE, "findStringSwitchCaseWithCache")
SEMANTICS_ATTR(BINARY_INTEGER_DESCRIPTION, "binaryInteger.description")
SEMANTICS_ATTR(SWIFT_CONCURRENT_ASYNC, "swift.concurrent.async")
SEMANTICS_ATTR(SWIFT_CONCURRENT_SAFE, "swift.concurrent.safe")
SEMANTICS_ATTR(SWIFT_CONCURRENT, "swift.concurrent")
SEMANTICS_ATTR(ARRAY_APPEND_CONTENTS_OF, "array.append_contentsOf")
SEMANTICS_ATTR(ARRAY_APPEND_ELEMENT, "array.append_element")
SEMANTICS_ATTR(ARRAY_CHECK_INDEX, "array.check_index")
SEMANTICS_ATTR(ARRAY_CHECK_SUBSCRIPT, "array.check_subscript")
SEMANTICS_ATTR(ARRAY_GET_CAPACITY, "array.get_capacity")
SEMANTICS_ATTR(ARRAY_GET_COUNT, "array.get_count")
SEMANTICS_ATTR(ARRAY_GET_ELEMENT, "array.get_element")
SEMANTICS_ATTR(ARRAY_GET_ELEMENT_ADDRESS, "array.get_element_address")
SEMANTICS_ATTR(ARRAY_INIT, "array.init")
SEMANTICS_ATTR(ARRAY_INIT_EMPTY, "array.init.empty")
SEMANTICS_ATTR(ARRAY_MAKE_MUTABLE, "array.make_mutable")
SEMANTICS_ATTR(ARRAY_END_MUTATION, "array.end_mutation")
SEMANTICS_ATTR(ARRAY_MUTATE_UNKNOWN, "array.mutate_unknown")
SEMANTICS_ATTR(ARRAY_PROPS_IS_NATIVE_TYPE_CHECKED, "array.props.isNativeTypeChecked")
SEMANTICS_ATTR(ARRAY_RESERVE_CAPACITY_FOR_APPEND, "array.reserve_capacity_for_append")
SEMANTICS_ATTR(ARRAY_UNINITIALIZED, "array.uninitialized")
SEMANTICS_ATTR(ARRAY_WITH_UNSAFE_MUTABLE_BUFFER_POINTER, "array.withUnsafeMutableBufferPointer")
SEMANTICS_ATTR(ARRAY_COUNT, "array.count")
SEMANTICS_ATTR(ARRAY_DEALLOC_UNINITIALIZED, "array.dealloc_uninitialized")
SEMANTICS_ATTR(ARRAY_UNINITIALIZED_INTRINSIC, "array.uninitialized_intrinsic")
SEMANTICS_ATTR(ARRAY_FINALIZE_INTRINSIC, "array.finalize_intrinsic")
SEMANTICS_ATTR(ARRAY_GET_CONTIGUOUSARRAYSTORAGETYPE, "array.getContiguousArrayStorageType")
SEMANTICS_ATTR(SEQUENCE_FOR_EACH, "sequence.forEach")
SEMANTICS_ATTR(TYPENAME, "typeName")
SEMANTICS_ATTR(OPTIMIZE_SIL_SPECIALIZE_GENERIC_NEVER, "optimize.sil.specialize.generic.never")
SEMANTICS_ATTR(OPTIMIZE_SIL_SPECIALIZE_GENERIC_PARTIAL_NEVER,
"optimize.sil.specialize.generic.partial.never")
SEMANTICS_ATTR(OPTIMIZE_SIL_SPECIALIZE_GENERIC_SIZE_NEVER,
"optimize.sil.specialize.generic.size.never")
SEMANTICS_ATTR(OPTIMIZE_SIL_SPECIALIZE_OWNED2GUARANTEE_NEVER,
"optimize.sil.specialize.owned2guarantee.never")
// To be used on a nominal type declaration.
// Assumes that a class (or class references inside a nominal type) are immortal.
// ARC operations on such types can be eliminated.
// If specified on a protocol declaration, all types which conform to that protocol
// are assumed to be immortal.
SEMANTICS_ATTR(ARC_IMMORTAL, "arc.immortal")
SEMANTICS_ATTR(OSLOG_MESSAGE_TYPE, "oslog.message.type")
SEMANTICS_ATTR(OSLOG_MESSAGE_INIT_INTERPOLATION, "oslog.message.init_interpolation")
SEMANTICS_ATTR(OSLOG_MESSAGE_INIT_STRING_LITERAL, "oslog.message.init_stringliteral")
SEMANTICS_ATTR(OSLOG_REQUIRES_CONSTANT_ARGUMENTS, "oslog.requires_constant_arguments")
SEMANTICS_ATTR(OSLOG_LOG_WITH_LEVEL, "oslog.log_with_level")
SEMANTICS_ATTR(ATOMICS_REQUIRES_CONSTANT_ORDERINGS, "atomics.requires_constant_orderings")
SEMANTICS_ATTR(TYPE_CHECKER_OPEN_EXISTENTIAL, "typechecker._openExistential(_:do:)")
SEMANTICS_ATTR(TYPE_CHECKER_TYPE, "typechecker.type(of:)")
SEMANTICS_ATTR(TYPE_CHECKER_WITHOUT_ACTUALLY_ESCAPING, "typechecker.withoutActuallyEscaping(_:do:)")
SEMANTICS_ATTR(AVAILABILITY_OSVERSION, "availability.osversion")
SEMANTICS_ATTR(CONSTANT_EVALUABLE, "constant_evaluable")
SEMANTICS_ATTR(EXIT, "exit")
SEMANTICS_ATTR(FASTPATH, "fastpath")
SEMANTICS_ATTR(SLOWPATH, "slowpath")
SEMANTICS_ATTR(PROGRAMTERMINATION_POINT, "programtermination_point")
SEMANTICS_ATTR(CONVERT_TO_OBJECTIVE_C, "convertToObjectiveC")
SEMANTICS_ATTR(KEYPATH_KVC_KEY_PATH_STRING, "keypath.kvcKeyPathString")
SEMANTICS_ATTR(KEYPATH_MUST_BE_VALID_FOR_KVO, "keypath.mustBeValidForKVO")
/// The prefix used to force opt-remarks to be emitted in a specific function.
///
/// If used just by itself "optremark", it is assumed that /all/ opt remarks
/// should be emitted. Otherwise, one can add a suffix after a '.' that
/// specifies a pass to emit opt-remarks from. So for instance to get just
/// information from 'sil-opt-remark-gen', one would write:
/// "optremark.sil-opt-remark-gen". One can add as many as one wishes. Keep in
/// mind that if the function itself is inlined, one will lose the optremark so
/// consider inlining where to put these.
SEMANTICS_ATTR(FORCE_EMIT_OPT_REMARK_PREFIX, "optremark")
/// An attribute that when attached to a class causes instances of the class to
/// be forbidden from having associated objects set upon them. This is only used
/// for testing purposes.
SEMANTICS_ATTR(OBJC_FORBID_ASSOCIATED_OBJECTS, "objc.forbidAssociatedObjects")
SEMANTICS_ATTR(LIFETIMEMANAGEMENT_MOVE, "lifetimemanagement.move")
SEMANTICS_ATTR(LIFETIMEMANAGEMENT_COPY, "lifetimemanagement.copy")
SEMANTICS_ATTR(NO_PERFORMANCE_ANALYSIS, "no_performance_analysis")
// A flag used to turn off moveonly diagnostics on a function due to an earlier
// pass that ran. If we emit a diagnose invalid escaping captures error due to
// an inout being escaped into an escaping closure, we do not want to emit move
// errors in the closure. This is because SILGen today assumes that we will error
// in such cases and thus does not emit markers in said function for the inout.
// This then causes us to emit spurious "found a copy of a noncopyable value"
// errors that may cause the user to think there is a bug in the compiler.
SEMANTICS_ATTR(NO_MOVEONLY_DIAGNOSTICS, "sil.optimizer.moveonly.diagnostic.ignore")
// Tell the move-only checker to delete this function body instead of performing
// diagnostics if the function is not used at the time of checking.
// When allocbox to stack specializes a function, we do not want to emit move
// errors twice, once on the specialized and once on the original
// function. The semantics of the closure with regards to move-only values may
// also be dependent on stack promotion. Therefore, we mark the original with
// this attribute, so that after it's promoted, the original function gets deleted
// instead of raising spurious diagnostics.
SEMANTICS_ATTR(MOVEONLY_DELETE_IF_UNUSED, "sil.optimizer.moveonly.delete_if_unused")
// Force the use of the frame pointer for the specified function
SEMANTICS_ATTR(USE_FRAME_POINTER, "use_frame_pointer")
#undef SEMANTICS_ATTR