Skip to content

Commit 2534af7

Browse files
authored
Merge pull request swiftlang#27942 from ravikandhadai/oslog-append-interpolation-consteval-improved
2 parents 312fefc + 861c0aa commit 2534af7

15 files changed

+282
-193
lines changed

include/swift/AST/DiagnosticsSIL.def

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -408,11 +408,17 @@ NOTE(constexpr_unsupported_instruction_found_here,none, "operation"
408408

409409
NOTE(constexpr_found_callee_with_no_body, none,
410410
"encountered call to '%0' whose body is not available. "
411-
"Imported functions must be marked '@inlinable' to constant evaluate.",
411+
"Imported functions must be marked '@inlinable' to constant evaluate",
412412
(StringRef))
413413
NOTE(constexpr_callee_with_no_body, none,
414414
"%select{|calls a }0function whose body is not available", (bool))
415415

416+
NOTE(constexpr_found_call_with_unknown_arg, none,
417+
"encountered call to '%0' where the %1 argument is not a constant",
418+
(StringRef, StringRef))
419+
NOTE(constexpr_call_with_unknown_arg, none,
420+
"%select{|makes a }0function call with non-constant arguments", (bool))
421+
416422
NOTE(constexpr_untracked_sil_value_use_found, none,
417423
"encountered use of a variable not tracked by the evaluator", ())
418424
NOTE(constexpr_untracked_sil_value_used_here, none,
@@ -509,24 +515,23 @@ NOTE(try_branch_doesnt_yield, none, "missing yield when error is "
509515

510516
// OS log optimization diagnostics.
511517

512-
ERROR(oslog_message_argument_not_found, none, "no argument of type %0 in "
513-
" the os log call", (Identifier))
518+
ERROR(oslog_non_const_interpolation_options, none, "interpolation arguments "
519+
"like format and privacy options must be constants", ())
514520

515-
ERROR(oslog_dynamic_message, none, "os log methods must be passed a string "
516-
"interpolation literal. 'OSLogMessage' must not be constructed explicitly",
517-
())
521+
ERROR(oslog_const_evaluable_fun_error, none, "evaluation of constant-evaluable "
522+
"function '%0' failed", (StringRef))
518523

519-
ERROR(oslog_const_evaluation_error, none, "constant evaluating 'OSLogMessage'"
520-
"implementation failed.", ())
524+
ERROR(oslog_fail_stop_error, none, "constant evaluation of log call failed "
525+
"with fatal error", ())
521526

522-
ERROR(oslog_non_constant_message, none, "'OSLogMessage' struct is "
523-
"unoptimizable: 'init' is not constant evaluable", ())
527+
ERROR(oslog_non_constant_message, none, "'OSLogMessage' instance passed to the "
528+
"log call is not a constant", ())
524529

525-
ERROR(oslog_non_constant_interpolation, none, "'OSLogInterpolation' struct is "
526-
"unoptimizable: 'init' is not constant evaluable", ())
530+
ERROR(oslog_non_constant_interpolation, none, "'OSLogInterpolation' instance "
531+
"passed to 'OSLogMessage.init' is not a constant", ())
527532

528533
ERROR(oslog_property_not_constant, none, "'OSLogInterpolation.%0' is not a "
529-
"constant: formatting and privacy options must be literals", (StringRef))
534+
"constant", (StringRef))
530535

531536
ERROR(global_string_pointer_on_non_constant, none, "globalStringTablePointer "
532537
"builtin must used only on string literals", ())

include/swift/SIL/SILConstants.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ class UnknownReason {
107107
/// Encountered an instruction not supported by the interpreter.
108108
UnsupportedInstruction,
109109

110+
/// Encountered a function call whose arguments are not constants.
111+
CallArgumentUnknown,
112+
110113
/// Encountered a function call where the body of the called function is
111114
/// not available.
112115
CalleeImplementationUnknown,
@@ -145,8 +148,9 @@ class UnknownReason {
145148

146149
// Auxiliary information for different unknown kinds.
147150
union {
148-
SILFunction *function;
149-
const char *trapMessage;
151+
SILFunction *function; // For CalleeImplementationUnknown
152+
const char *trapMessage; // For Trap.
153+
unsigned argumentIndex; // For CallArgumentUnknown
150154
} payload;
151155

152156
public:
@@ -156,6 +160,7 @@ class UnknownReason {
156160
switch (kind) {
157161
case UnknownKind::CalleeImplementationUnknown:
158162
case UnknownKind::Trap:
163+
case UnknownKind::CallArgumentUnknown:
159164
return true;
160165
default:
161166
return false;
@@ -200,6 +205,18 @@ class UnknownReason {
200205
assert(kind == UnknownKind::Trap);
201206
return payload.trapMessage;
202207
}
208+
209+
static UnknownReason createCallArgumentUnknown(unsigned argIndex) {
210+
UnknownReason reason;
211+
reason.kind = UnknownKind::CallArgumentUnknown;
212+
reason.payload.argumentIndex = argIndex;
213+
return reason;
214+
}
215+
216+
unsigned getArgumentIndex() {
217+
assert(kind == UnknownKind::CallArgumentUnknown);
218+
return payload.argumentIndex;
219+
}
203220
};
204221

205222
/// This is the symbolic value tracked for each SILValue in a scope. We

include/swift/SILOptimizer/Utils/ConstExpr.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -187,11 +187,6 @@ class ConstExprStepEvaluator {
187187

188188
Optional<SymbolicValue> lookupConstValue(SILValue value);
189189

190-
/// Returns true if and only if `errorVal` denotes an error that requires
191-
/// aborting interpretation and returning the error. Skipping an instruction
192-
/// that produces such errors is not a valid behavior.
193-
bool isFailStopError(SymbolicValue errorVal);
194-
195190
/// Return the number of instructions evaluated for the last `evaluate`
196191
/// operation. This could be used by the clients to limit the number of
197192
/// instructions that should be evaluated by the step-wise evaluator.
@@ -212,7 +207,18 @@ class ConstExprStepEvaluator {
212207
void dumpState();
213208
};
214209

210+
bool isConstantEvaluable(SILFunction *fun);
211+
212+
/// Return true if and only if the given function \p fun is specially modeled
213+
/// by the constant evaluator. These are typically functions in the standard
214+
/// library, such as String.+=, Array.append, whose semantics is built into the
215+
/// evaluator.
215216
bool isKnownConstantEvaluableFunction(SILFunction *fun);
216217

218+
/// Return true if and only if \p errorVal denotes an error that requires
219+
/// aborting interpretation and returning the error. Skipping an instruction
220+
/// that produces such errors is not a valid behavior.
221+
bool isFailStopError(SymbolicValue errorVal);
222+
217223
} // end namespace swift
218224
#endif

lib/SIL/SILConstants.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ using namespace swift;
2020

2121
namespace swift {
2222
llvm::cl::opt<unsigned>
23-
ConstExprLimit("constexpr-limit", llvm::cl::init(1024),
23+
ConstExprLimit("constexpr-limit", llvm::cl::init(2048),
2424
llvm::cl::desc("Number of instructions interpreted in a"
2525
" constexpr function"));
2626
}
@@ -792,6 +792,12 @@ static void getWitnessMethodName(WitnessMethodInst *witnessMethodInst,
792792
}
793793
}
794794

795+
/// A helper function to pretty print function names in diagnostics.
796+
static std::string demangleSymbolNameForDiagnostics(StringRef name) {
797+
return Demangle::demangleSymbolAsString(
798+
name, Demangle::DemangleOptions::SimplifiedUIDemangleOptions());
799+
}
800+
795801
/// Given that this is an 'Unknown' value, emit diagnostic notes providing
796802
/// context about what the problem is. Specifically, point to interesting
797803
/// source locations and function calls in the call stack.
@@ -910,14 +916,30 @@ void SymbolicValue::emitUnknownDiagnosticNotes(SILLocation fallbackLoc) {
910916
case UnknownReason::CalleeImplementationUnknown: {
911917
SILFunction *callee = unknownReason.getCalleeWithoutImplmentation();
912918
std::string demangledCalleeName =
913-
Demangle::demangleSymbolAsString(callee->getName());
919+
demangleSymbolNameForDiagnostics(callee->getName());
914920
diagnose(ctx, diagLoc, diag::constexpr_found_callee_with_no_body,
915921
StringRef(demangledCalleeName));
916922
if (emitTriggerLocInDiag)
917923
diagnose(ctx, triggerLoc, diag::constexpr_callee_with_no_body,
918924
triggerLocSkipsInternalLocs);
919925
return;
920926
}
927+
case UnknownReason::CallArgumentUnknown: {
928+
unsigned argNumber = unknownReason.getArgumentIndex() + 1;
929+
ApplyInst *call = dyn_cast<ApplyInst>(unknownNode);
930+
assert(call);
931+
SILFunction *callee = call->getCalleeFunction();
932+
assert(callee);
933+
std::string demangledCalleeName =
934+
demangleSymbolNameForDiagnostics(callee->getName());
935+
diagnose(ctx, diagLoc, diag::constexpr_found_call_with_unknown_arg,
936+
demangledCalleeName,
937+
(Twine(argNumber) + llvm::getOrdinalSuffix(argNumber)).str());
938+
if (emitTriggerLocInDiag)
939+
diagnose(ctx, triggerLoc, diag::constexpr_call_with_unknown_arg,
940+
triggerLocSkipsInternalLocs);
941+
return;
942+
}
921943
case UnknownReason::UntrackedSILValue:
922944
diagnose(ctx, diagLoc, diag::constexpr_untracked_sil_value_use_found);
923945
if (emitTriggerLocInDiag)

0 commit comments

Comments
 (0)