mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 22:02:23 +01:00
Replace the large and growing `TryEvalInstInContext` function with one function per kind. While we still have special-case handling for a small number of instruction kinds, most instructions are now handled either fully automatically or use a common codepath that evaluates the instruction operands and then performs an eval-context-independent evaluation of the instruction. To support this, `InstConstantKind` is expanded to describe more fine-grained details about how each kind of instruction interacts with constant evaluation. Also, the operand kinds of instructions become slightly more fine-grained: we now distinguish between operands that describe the destination of an initializing expression (`DestInstId`) from other `InstId` operands, because `DestInstId` operands need different treatment during constant evaluation. In particular, an initializing expression can have a constant value even if its destination is non-constant or has not yet been set, because evaluation of an initializing expression doesn't include the store to the destination. Some minor test changes: - We now more consistently propagate errors into the results of constant evaluation, so more instructions that depend on errors have a constant value of `<error>`. - Diagnostic location for invalid array types now point at the whole array type rather than the array index expression, because `EvalConstantinst` doesn't have access to the original expression. - Diagnostic for failed `RequireCompleteType` doesn't print the original type any more because `EvalConstantInst` doesn't have access to the original expression. As a follow-up, some of this -- in particular, the `EvalConstantInst` overloads -- will be moved to a separate file, in an effort to split the overall constant evaluation machinery apart from the logic to evaluate each individual kind of instruction.
57 lines
2.3 KiB
Plaintext
57 lines
2.3 KiB
Plaintext
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
// AUTOUPDATE
|
|
// TIP: To test this file alone, run:
|
|
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/pointer/fail_deref_function.carbon
|
|
// TIP: To dump output, run:
|
|
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/pointer/fail_deref_function.carbon
|
|
|
|
fn A() {
|
|
// CHECK:STDERR: fail_deref_function.carbon:[[@LINE+4]]:4: error: expression cannot be used as a value [UseOfNonExprAsValue]
|
|
// CHECK:STDERR: *A;
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
*A;
|
|
// CHECK:STDERR: fail_deref_function.carbon:[[@LINE+4]]:3: error: expression cannot be used as a value [UseOfNonExprAsValue]
|
|
// CHECK:STDERR: A->foo;
|
|
// CHECK:STDERR: ^
|
|
// CHECK:STDERR:
|
|
A->foo;
|
|
}
|
|
|
|
// CHECK:STDOUT: --- fail_deref_function.carbon
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: constants {
|
|
// CHECK:STDOUT: %A.type: type = fn_type @A [concrete]
|
|
// CHECK:STDOUT: %A: %A.type = struct_value () [concrete]
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: imports {
|
|
// CHECK:STDOUT: %Core: <namespace> = namespace file.%Core.import, [concrete] {
|
|
// CHECK:STDOUT: import Core//prelude
|
|
// CHECK:STDOUT: import Core//prelude/...
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: file {
|
|
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
|
|
// CHECK:STDOUT: .Core = imports.%Core
|
|
// CHECK:STDOUT: .A = %A.decl
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT: %Core.import = import Core
|
|
// CHECK:STDOUT: %A.decl: %A.type = fn_decl @A [concrete = constants.%A] {} {}
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: fn @A() {
|
|
// CHECK:STDOUT: !entry:
|
|
// CHECK:STDOUT: %A.ref.loc16: %A.type = name_ref A, file.%A.decl [concrete = constants.%A]
|
|
// CHECK:STDOUT: %.loc16: ref <error> = deref <error> [concrete = <error>]
|
|
// CHECK:STDOUT: %A.ref.loc21: %A.type = name_ref A, file.%A.decl [concrete = constants.%A]
|
|
// CHECK:STDOUT: %.loc21: ref <error> = deref <error> [concrete = <error>]
|
|
// CHECK:STDOUT: %foo.ref: <error> = name_ref foo, <error> [concrete = <error>]
|
|
// CHECK:STDOUT: return
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|