[torque] better static assert error messages
When mksnapshot fails on a static assert in Torque, print the statement and position from the Torque source. To enable special treatment, change the syntax of static asserts in Torque from StaticAssert() to static_assert() to align with assert() and check() statements. Bug: v8:7793 Change-Id: Idda8e3c342bdcefc893ff297f8d7727d2734c221 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2317314 Commit-Queue: Tobias Tebbi <tebbi@chromium.org> Reviewed-by: Seth Brenith <seth.brenith@microsoft.com> Cr-Commit-Position: refs/heads/master@{#69069}
This commit is contained in:
parent
c0ed24a0e5
commit
a7ca5b0f6b
@ -473,7 +473,6 @@ extern macro SelectBooleanConstant(bool): Boolean;
|
||||
extern macro Print(constexpr string);
|
||||
extern macro Print(constexpr string, Object);
|
||||
extern macro Comment(constexpr string);
|
||||
extern macro StaticAssert(bool);
|
||||
extern macro Print(Object);
|
||||
extern macro DebugBreak();
|
||||
|
||||
@ -1618,7 +1617,7 @@ transitioning builtin FastCreateDataProperty(implicit context: Context)(
|
||||
}
|
||||
|
||||
macro VerifiedUnreachable(): never {
|
||||
StaticAssert(false);
|
||||
static_assert(false);
|
||||
unreachable;
|
||||
}
|
||||
|
||||
|
@ -117,7 +117,7 @@ IfInBounds(String, uintptr, uintptr), IfOutOfBounds {
|
||||
// check.
|
||||
const kMaxStringLengthFitsSmi: constexpr bool =
|
||||
kStringMaxLengthUintptr < kSmiMaxValue;
|
||||
StaticAssert(kMaxStringLengthFitsSmi);
|
||||
static_assert(kMaxStringLengthFitsSmi);
|
||||
if (index >= length) goto IfOutOfBounds;
|
||||
goto IfInBounds(string, index, length);
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ FromConstexpr<Number, constexpr int31>(i: constexpr int31): Number {
|
||||
}
|
||||
FromConstexpr<uint8, constexpr int31>(i: constexpr int31): uint8 {
|
||||
const i: uint32 = i;
|
||||
StaticAssert(i <= 255);
|
||||
static_assert(i <= 255);
|
||||
return %RawDownCast<uint8>(i);
|
||||
}
|
||||
FromConstexpr<Number, constexpr Smi>(s: constexpr Smi): Number {
|
||||
|
@ -100,7 +100,7 @@ transitioning macro MorphAndEnqueuePromiseReaction(implicit context: Context)(
|
||||
primaryHandler = promiseReaction.fulfill_handler;
|
||||
secondaryHandler = promiseReaction.reject_handler;
|
||||
} else {
|
||||
StaticAssert(reactionType == kPromiseReactionReject);
|
||||
static_assert(reactionType == kPromiseReactionReject);
|
||||
primaryHandler = promiseReaction.reject_handler;
|
||||
secondaryHandler = promiseReaction.fulfill_handler;
|
||||
}
|
||||
@ -114,7 +114,7 @@ transitioning macro MorphAndEnqueuePromiseReaction(implicit context: Context)(
|
||||
// Morph {current} from a PromiseReaction into a PromiseReactionJobTask
|
||||
// and schedule that on the microtask queue. We try to minimize the number
|
||||
// of stores here to avoid screwing up the store buffer.
|
||||
StaticAssert(
|
||||
static_assert(
|
||||
kPromiseReactionSize ==
|
||||
kPromiseReactionJobTaskSizeOfAllPromiseReactionJobTasks);
|
||||
if constexpr (reactionType == kPromiseReactionFulfill) {
|
||||
@ -125,14 +125,14 @@ transitioning macro MorphAndEnqueuePromiseReaction(implicit context: Context)(
|
||||
promiseReactionJobTask.argument = argument;
|
||||
promiseReactionJobTask.context = handlerContext;
|
||||
EnqueueMicrotask(handlerContext, promiseReactionJobTask);
|
||||
StaticAssert(
|
||||
static_assert(
|
||||
kPromiseReactionFulfillHandlerOffset ==
|
||||
kPromiseReactionJobTaskHandlerOffset);
|
||||
StaticAssert(
|
||||
static_assert(
|
||||
kPromiseReactionPromiseOrCapabilityOffset ==
|
||||
kPromiseReactionJobTaskPromiseOrCapabilityOffset);
|
||||
} else {
|
||||
StaticAssert(reactionType == kPromiseReactionReject);
|
||||
static_assert(reactionType == kPromiseReactionReject);
|
||||
*UnsafeConstCast(&promiseReaction.map) =
|
||||
PromiseRejectReactionJobTaskMapConstant();
|
||||
const promiseReactionJobTask =
|
||||
@ -141,7 +141,7 @@ transitioning macro MorphAndEnqueuePromiseReaction(implicit context: Context)(
|
||||
promiseReactionJobTask.context = handlerContext;
|
||||
promiseReactionJobTask.handler = primaryHandler;
|
||||
EnqueueMicrotask(handlerContext, promiseReactionJobTask);
|
||||
StaticAssert(
|
||||
static_assert(
|
||||
kPromiseReactionPromiseOrCapabilityOffset ==
|
||||
kPromiseReactionJobTaskPromiseOrCapabilityOffset);
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ macro RejectPromiseReactionJob(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
StaticAssert(reactionType == kPromiseReactionFulfill);
|
||||
static_assert(reactionType == kPromiseReactionFulfill);
|
||||
// We have to call out to the dedicated PromiseRejectReactionJob
|
||||
// builtin here, instead of just doing the work inline, as otherwise
|
||||
// the catch predictions in the debugger will be wrong, which just
|
||||
@ -79,7 +79,7 @@ macro PromiseReactionJob(
|
||||
return FuflfillPromiseReactionJob(
|
||||
context, promiseOrCapability, argument, reactionType);
|
||||
} else {
|
||||
StaticAssert(reactionType == kPromiseReactionReject);
|
||||
static_assert(reactionType == kPromiseReactionReject);
|
||||
return RejectPromiseReactionJob(
|
||||
context, promiseOrCapability, argument, reactionType);
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ transitioning macro RegExpPrototypeMatchBody(implicit context: Context)(
|
||||
// length is less than the maximal Smi value.
|
||||
const kMaxStringLengthFitsSmi: constexpr bool =
|
||||
kStringMaxLengthUintptr < kSmiMaxValue;
|
||||
StaticAssert(kMaxStringLengthFitsSmi);
|
||||
static_assert(kMaxStringLengthFitsSmi);
|
||||
assert(TaggedIsPositiveSmi(newLastIndex));
|
||||
}
|
||||
|
||||
|
@ -219,6 +219,8 @@ macro DownCastForTorqueClass<T : type extends HeapObject>(o: HeapObject):
|
||||
return %RawDownCast<T>(o);
|
||||
}
|
||||
|
||||
extern macro StaticAssert(bool, constexpr string);
|
||||
|
||||
} // namespace torque_internal
|
||||
|
||||
// Indicates that an array-field should not be initialized.
|
||||
|
@ -3083,7 +3083,9 @@ void InstructionSelector::VisitUnreachable(Node* node) {
|
||||
void InstructionSelector::VisitStaticAssert(Node* node) {
|
||||
Node* asserted = node->InputAt(0);
|
||||
asserted->Print(4);
|
||||
FATAL("Expected turbofan static assert to hold, but got non-true input!\n");
|
||||
FATAL(
|
||||
"Expected Turbofan static assert to hold, but got non-true input:\n %s",
|
||||
StaticAssertSourceOf(node->op()));
|
||||
}
|
||||
|
||||
void InstructionSelector::VisitDeadValue(Node* node) {
|
||||
|
@ -495,8 +495,8 @@ void CodeAssembler::Comment(std::string str) {
|
||||
raw_assembler()->Comment(str);
|
||||
}
|
||||
|
||||
void CodeAssembler::StaticAssert(TNode<BoolT> value) {
|
||||
raw_assembler()->StaticAssert(value);
|
||||
void CodeAssembler::StaticAssert(TNode<BoolT> value, const char* source) {
|
||||
raw_assembler()->StaticAssert(value, source);
|
||||
}
|
||||
|
||||
void CodeAssembler::SetSourcePosition(const char* file, int line) {
|
||||
|
@ -597,7 +597,8 @@ class V8_EXPORT_PRIVATE CodeAssembler {
|
||||
Comment(s.str());
|
||||
}
|
||||
|
||||
void StaticAssert(TNode<BoolT> value);
|
||||
void StaticAssert(TNode<BoolT> value,
|
||||
const char* source = "unknown position");
|
||||
|
||||
// The following methods refer to source positions in CSA or Torque code
|
||||
// compiled during mksnapshot, not JS compiled at runtime.
|
||||
|
@ -455,22 +455,21 @@ IfValueParameters const& IfValueParametersOf(const Operator* op) {
|
||||
return OpParameter<IfValueParameters>(op);
|
||||
}
|
||||
|
||||
#define COMMON_CACHED_OP_LIST(V) \
|
||||
V(Dead, Operator::kFoldable, 0, 0, 0, 1, 1, 1) \
|
||||
V(Unreachable, Operator::kFoldable, 0, 1, 1, 1, 1, 0) \
|
||||
V(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
|
||||
V(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
|
||||
V(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
|
||||
V(IfException, Operator::kKontrol, 0, 1, 1, 1, 1, 1) \
|
||||
V(Throw, Operator::kKontrol, 0, 1, 1, 0, 0, 1) \
|
||||
V(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1) \
|
||||
V(LoopExit, Operator::kKontrol, 0, 0, 2, 0, 0, 1) \
|
||||
V(LoopExitValue, Operator::kPure, 1, 0, 1, 1, 0, 0) \
|
||||
V(LoopExitEffect, Operator::kNoThrow, 0, 1, 1, 0, 1, 0) \
|
||||
V(Checkpoint, Operator::kKontrol, 0, 1, 1, 0, 1, 0) \
|
||||
V(FinishRegion, Operator::kKontrol, 1, 1, 0, 1, 1, 0) \
|
||||
V(Retain, Operator::kKontrol, 1, 1, 0, 0, 1, 0) \
|
||||
V(StaticAssert, Operator::kFoldable, 1, 1, 0, 0, 1, 0)
|
||||
#define COMMON_CACHED_OP_LIST(V) \
|
||||
V(Dead, Operator::kFoldable, 0, 0, 0, 1, 1, 1) \
|
||||
V(Unreachable, Operator::kFoldable, 0, 1, 1, 1, 1, 0) \
|
||||
V(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
|
||||
V(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
|
||||
V(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
|
||||
V(IfException, Operator::kKontrol, 0, 1, 1, 1, 1, 1) \
|
||||
V(Throw, Operator::kKontrol, 0, 1, 1, 0, 0, 1) \
|
||||
V(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1) \
|
||||
V(LoopExit, Operator::kKontrol, 0, 0, 2, 0, 0, 1) \
|
||||
V(LoopExitValue, Operator::kPure, 1, 0, 1, 1, 0, 0) \
|
||||
V(LoopExitEffect, Operator::kNoThrow, 0, 1, 1, 0, 1, 0) \
|
||||
V(Checkpoint, Operator::kKontrol, 0, 1, 1, 0, 1, 0) \
|
||||
V(FinishRegion, Operator::kKontrol, 1, 1, 0, 1, 1, 0) \
|
||||
V(Retain, Operator::kKontrol, 1, 1, 0, 0, 1, 0)
|
||||
|
||||
#define CACHED_BRANCH_LIST(V) \
|
||||
V(None, CriticalSafetyCheck) \
|
||||
@ -939,6 +938,12 @@ const Operator* CommonOperatorBuilder::Return(int value_input_count) {
|
||||
value_input_count + 1, 1, 1, 0, 0, 1); // counts
|
||||
}
|
||||
|
||||
const Operator* CommonOperatorBuilder::StaticAssert(const char* source) {
|
||||
return zone()->New<Operator1<const char*>>(
|
||||
IrOpcode::kStaticAssert, Operator::kFoldable, "StaticAssert", 1, 1, 0, 0,
|
||||
1, 0, source);
|
||||
}
|
||||
|
||||
const Operator* CommonOperatorBuilder::Branch(BranchHint hint,
|
||||
IsSafetyCheck is_safety_check) {
|
||||
#define CACHED_BRANCH(Hint, IsCheck) \
|
||||
@ -1248,6 +1253,11 @@ const StringConstantBase* StringConstantBaseOf(const Operator* op) {
|
||||
return OpParameter<const StringConstantBase*>(op);
|
||||
}
|
||||
|
||||
const char* StaticAssertSourceOf(const Operator* op) {
|
||||
DCHECK_EQ(IrOpcode::kStaticAssert, op->opcode());
|
||||
return OpParameter<const char*>(op);
|
||||
}
|
||||
|
||||
const Operator* CommonOperatorBuilder::RelocatableInt32Constant(
|
||||
int32_t value, RelocInfo::Mode rmode) {
|
||||
return zone()->New<Operator1<RelocatablePtrConstantInfo>>( // --
|
||||
|
@ -449,6 +449,8 @@ V8_EXPORT_PRIVATE Handle<HeapObject> HeapConstantOf(const Operator* op)
|
||||
const StringConstantBase* StringConstantBaseOf(const Operator* op)
|
||||
V8_WARN_UNUSED_RESULT;
|
||||
|
||||
const char* StaticAssertSourceOf(const Operator* op);
|
||||
|
||||
// Interface for building common operators that can be used at any level of IR,
|
||||
// including JavaScript, mid-level, and low-level.
|
||||
class V8_EXPORT_PRIVATE CommonOperatorBuilder final
|
||||
@ -459,7 +461,7 @@ class V8_EXPORT_PRIVATE CommonOperatorBuilder final
|
||||
const Operator* Dead();
|
||||
const Operator* DeadValue(MachineRepresentation rep);
|
||||
const Operator* Unreachable();
|
||||
const Operator* StaticAssert();
|
||||
const Operator* StaticAssert(const char* source);
|
||||
const Operator* End(size_t control_input_count);
|
||||
const Operator* Branch(BranchHint = BranchHint::kNone,
|
||||
IsSafetyCheck = IsSafetyCheck::kSafetyCheck);
|
||||
|
@ -285,7 +285,8 @@ Reduction JSIntrinsicLowering::ReduceTurbofanStaticAssert(Node* node) {
|
||||
} else {
|
||||
Node* value = NodeProperties::GetValueInput(node, 0);
|
||||
Node* effect = NodeProperties::GetEffectInput(node);
|
||||
Node* assert = graph()->NewNode(common()->StaticAssert(), value, effect);
|
||||
Node* assert = graph()->NewNode(
|
||||
common()->StaticAssert("%TurbofanStaticAssert"), value, effect);
|
||||
ReplaceWithValue(node, node, assert, nullptr);
|
||||
}
|
||||
return Changed(jsgraph_->UndefinedConstant());
|
||||
|
@ -680,8 +680,8 @@ void RawMachineAssembler::Comment(const std::string& msg) {
|
||||
AddNode(machine()->Comment(zone_buffer));
|
||||
}
|
||||
|
||||
void RawMachineAssembler::StaticAssert(Node* value) {
|
||||
AddNode(common()->StaticAssert(), value);
|
||||
void RawMachineAssembler::StaticAssert(Node* value, const char* source) {
|
||||
AddNode(common()->StaticAssert(source), value);
|
||||
}
|
||||
|
||||
Node* RawMachineAssembler::CallN(CallDescriptor* call_descriptor,
|
||||
|
@ -967,7 +967,7 @@ class V8_EXPORT_PRIVATE RawMachineAssembler {
|
||||
void DebugBreak();
|
||||
void Unreachable();
|
||||
void Comment(const std::string& msg);
|
||||
void StaticAssert(Node* value);
|
||||
void StaticAssert(Node* value, const char* source);
|
||||
|
||||
#if DEBUG
|
||||
void Bind(RawMachineLabel* label, AssemblerDebugInfo info);
|
||||
|
@ -709,13 +709,14 @@ struct DebugStatement : Statement {
|
||||
|
||||
struct AssertStatement : Statement {
|
||||
DEFINE_AST_NODE_LEAF_BOILERPLATE(AssertStatement)
|
||||
AssertStatement(SourcePosition pos, bool debug_only, Expression* expression,
|
||||
enum class AssertKind { kAssert, kCheck, kStaticAssert };
|
||||
AssertStatement(SourcePosition pos, AssertKind kind, Expression* expression,
|
||||
std::string source)
|
||||
: Statement(kKind, pos),
|
||||
debug_only(debug_only),
|
||||
kind(kind),
|
||||
expression(expression),
|
||||
source(std::move(source)) {}
|
||||
bool debug_only;
|
||||
AssertKind kind;
|
||||
Expression* expression;
|
||||
std::string source;
|
||||
};
|
||||
|
@ -17,6 +17,7 @@ namespace torque {
|
||||
static const char* const CONSTEXPR_TYPE_PREFIX = "constexpr ";
|
||||
static const char* const NEVER_TYPE_STRING = "never";
|
||||
static const char* const CONSTEXPR_BOOL_TYPE_STRING = "constexpr bool";
|
||||
static const char* const CONSTEXPR_STRING_TYPE_STRING = "constexpr string";
|
||||
static const char* const CONSTEXPR_INTPTR_TYPE_STRING = "constexpr intptr";
|
||||
static const char* const CONSTEXPR_INSTANCE_TYPE_TYPE_STRING =
|
||||
"constexpr InstanceType";
|
||||
@ -75,6 +76,7 @@ static const char* const UNINITIALIZED_ITERATOR_TYPE_STRING =
|
||||
static const char* const GENERIC_TYPE_INSTANTIATION_NAMESPACE_STRING =
|
||||
"_generic_type_instantiation_namespace";
|
||||
static const char* const FIXED_ARRAY_BASE_TYPE_STRING = "FixedArrayBase";
|
||||
static const char* const STATIC_ASSERT_MACRO_STRING = "StaticAssert";
|
||||
|
||||
static const char* const ANNOTATION_GENERATE_PRINT = "@generatePrint";
|
||||
static const char* const ANNOTATION_NO_VERIFIER = "@noVerifier";
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "src/base/optional.h"
|
||||
#include "src/common/globals.h"
|
||||
#include "src/torque/constants.h"
|
||||
#include "src/torque/csa-generator.h"
|
||||
#include "src/torque/declaration-visitor.h"
|
||||
#include "src/torque/global-context.h"
|
||||
@ -1047,7 +1048,19 @@ std::string FormatAssertSource(const std::string& str) {
|
||||
} // namespace
|
||||
|
||||
const Type* ImplementationVisitor::Visit(AssertStatement* stmt) {
|
||||
bool do_check = !stmt->debug_only || GlobalContext::force_assert_statements();
|
||||
if (stmt->kind == AssertStatement::AssertKind::kStaticAssert) {
|
||||
std::string message =
|
||||
"static_assert(" + stmt->source + ") at " + ToString(stmt->pos);
|
||||
GenerateCall(QualifiedName({"", TORQUE_INTERNAL_NAMESPACE_STRING},
|
||||
STATIC_ASSERT_MACRO_STRING),
|
||||
Arguments{{Visit(stmt->expression),
|
||||
VisitResult(TypeOracle::GetConstexprStringType(),
|
||||
StringLiteralQuote(message))},
|
||||
{}});
|
||||
return TypeOracle::GetVoidType();
|
||||
}
|
||||
bool do_check = stmt->kind != AssertStatement::AssertKind::kAssert ||
|
||||
GlobalContext::force_assert_statements();
|
||||
#if defined(DEBUG)
|
||||
do_check = true;
|
||||
#endif
|
||||
|
@ -487,11 +487,20 @@ base::Optional<ParseResult> MakeParameterList(
|
||||
|
||||
base::Optional<ParseResult> MakeAssertStatement(
|
||||
ParseResultIterator* child_results) {
|
||||
auto kind = child_results->NextAs<Identifier*>()->value;
|
||||
auto kind_string = child_results->NextAs<Identifier*>()->value;
|
||||
auto expr_with_source = child_results->NextAs<ExpressionWithSource>();
|
||||
DCHECK(kind == "assert" || kind == "check");
|
||||
AssertStatement::AssertKind kind;
|
||||
if (kind_string == "assert") {
|
||||
kind = AssertStatement::AssertKind::kAssert;
|
||||
} else if (kind_string == "check") {
|
||||
kind = AssertStatement::AssertKind::kCheck;
|
||||
} else if (kind_string == "static_assert") {
|
||||
kind = AssertStatement::AssertKind::kStaticAssert;
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
Statement* result = MakeNode<AssertStatement>(
|
||||
kind == "assert", expr_with_source.expression, expr_with_source.source);
|
||||
kind, expr_with_source.expression, expr_with_source.source);
|
||||
return ParseResult{result};
|
||||
}
|
||||
|
||||
@ -2400,8 +2409,8 @@ struct TorqueGrammar : Grammar {
|
||||
MakeTypeswitchStatement),
|
||||
Rule({Token("try"), &block, List<TryHandler*>(&tryHandler)},
|
||||
MakeTryLabelExpression),
|
||||
Rule({OneOf({"assert", "check"}), Token("("), &expressionWithSource,
|
||||
Token(")"), Token(";")},
|
||||
Rule({OneOf({"assert", "check", "static_assert"}), Token("("),
|
||||
&expressionWithSource, Token(")"), Token(";")},
|
||||
MakeAssertStatement),
|
||||
Rule({Token("while"), Token("("), expression, Token(")"), &statement},
|
||||
MakeWhileStatement),
|
||||
|
@ -166,6 +166,10 @@ class TypeOracle : public ContextualClass<TypeOracle> {
|
||||
return Get().GetBuiltinType(CONSTEXPR_BOOL_TYPE_STRING);
|
||||
}
|
||||
|
||||
static const Type* GetConstexprStringType() {
|
||||
return Get().GetBuiltinType(CONSTEXPR_STRING_TYPE_STRING);
|
||||
}
|
||||
|
||||
static const Type* GetConstexprIntPtrType() {
|
||||
return Get().GetBuiltinType(CONSTEXPR_INTPTR_TYPE_STRING);
|
||||
}
|
||||
|
@ -908,7 +908,7 @@ macro TestSliceEnumeration(implicit context: Context)(): Undefined {
|
||||
|
||||
@export
|
||||
macro TestStaticAssert() {
|
||||
StaticAssert(1 + 2 == 3);
|
||||
static_assert(1 + 2 == 3);
|
||||
}
|
||||
|
||||
class SmiBox extends HeapObject {
|
||||
@ -926,12 +926,12 @@ macro TestLoadEliminationFixed(implicit context: Context)() {
|
||||
const v1 = box.value;
|
||||
box.unrelated = 999;
|
||||
const v2 = (box.unrelated == 0) ? box.value : box.value;
|
||||
StaticAssert(TaggedEqual(v1, v2));
|
||||
static_assert(TaggedEqual(v1, v2));
|
||||
|
||||
box.value = 11;
|
||||
const v3 = box.value;
|
||||
const eleven: Smi = 11;
|
||||
StaticAssert(TaggedEqual(v3, eleven));
|
||||
static_assert(TaggedEqual(v3, eleven));
|
||||
}
|
||||
|
||||
@export
|
||||
@ -942,8 +942,8 @@ macro TestLoadEliminationVariable(implicit context: Context)() {
|
||||
const u1 = a.objects[box.value + 2];
|
||||
const v2 = a.objects[box.value];
|
||||
const u2 = a.objects[box.value + 2];
|
||||
StaticAssert(TaggedEqual(v1, v2));
|
||||
StaticAssert(TaggedEqual(u1, u2));
|
||||
static_assert(TaggedEqual(v1, v2));
|
||||
static_assert(TaggedEqual(u1, u2));
|
||||
}
|
||||
|
||||
@export
|
||||
@ -954,7 +954,7 @@ macro TestRedundantArrayElementCheck(implicit context: Context)(): Smi {
|
||||
if (a.objects[i] == TheHole) {
|
||||
return -1;
|
||||
} else {
|
||||
StaticAssert(false);
|
||||
static_assert(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1029,9 +1029,9 @@ macro TestBranchOnBoolOptimization(implicit context: Context)(input: Smi) {
|
||||
// If the two branches get combined into one, we should be able to determine
|
||||
// the value of {box} statically.
|
||||
if (BranchAndWriteResult(input, box)) {
|
||||
StaticAssert(box.value == 1);
|
||||
static_assert(box.value == 1);
|
||||
} else {
|
||||
StaticAssert(box.value == 2);
|
||||
static_assert(box.value == 2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1135,23 +1135,23 @@ macro TestBitFieldMultipleFlags(a: bool, b: int32, c: bool) {
|
||||
const f = TestBitFieldStruct4{a: a, b: b, c: c};
|
||||
let simpleExpression = f.a & f.b == 3 & !f.c;
|
||||
let expectedReduction = (Signed(f) & 0x1f) == Convert<int32>(1 | 3 << 1);
|
||||
StaticAssert(simpleExpression == expectedReduction);
|
||||
static_assert(simpleExpression == expectedReduction);
|
||||
simpleExpression = !f.a & f.b == 4 & f.c;
|
||||
expectedReduction = (Signed(f) & 0x1f) == Convert<int32>(4 << 1 | 1 << 4);
|
||||
StaticAssert(simpleExpression == expectedReduction);
|
||||
static_assert(simpleExpression == expectedReduction);
|
||||
simpleExpression = f.b == 0 & f.c;
|
||||
expectedReduction = (Signed(f) & 0x1e) == Convert<int32>(1 << 4);
|
||||
StaticAssert(simpleExpression == expectedReduction);
|
||||
static_assert(simpleExpression == expectedReduction);
|
||||
simpleExpression = f.a & f.c;
|
||||
expectedReduction = (Signed(f) & 0x11) == Convert<int32>(1 | 1 << 4);
|
||||
StaticAssert(simpleExpression == expectedReduction);
|
||||
static_assert(simpleExpression == expectedReduction);
|
||||
const f2 = TestBitFieldStruct5{b: b, a: a, c: c};
|
||||
simpleExpression = !f2.a & f2.b == 1234 & f2.c;
|
||||
expectedReduction = (Signed(f2) & 0x1fffff) == Convert<int32>(1234 | 1 << 20);
|
||||
StaticAssert(simpleExpression == expectedReduction);
|
||||
static_assert(simpleExpression == expectedReduction);
|
||||
simpleExpression = !f2.a & !f2.c;
|
||||
expectedReduction = (Signed(f2) & 0x180000) == Convert<int32>(0);
|
||||
StaticAssert(simpleExpression == expectedReduction);
|
||||
static_assert(simpleExpression == expectedReduction);
|
||||
}
|
||||
|
||||
@export
|
||||
|
Loading…
Reference in New Issue
Block a user