diff --git a/NEWS.md b/NEWS.md index 0ce4a5cc458d5..916781b397dbe 100644 --- a/NEWS.md +++ b/NEWS.md @@ -30,6 +30,7 @@ New language features for example `a, b... = [1, 2, 3]`. This syntax is implemented using `Base.rest`, which can be overloaded to customize its behavior for different collection types ([#37410]). +* The default behavior of observing `@inbounds` declarations is now an option via `auto` in `--check-bounds=yes|no|auto` ([#41551]) Language changes ---------------- diff --git a/base/util.jl b/base/util.jl index 81399720c84a3..0466614278d5e 100644 --- a/base/util.jl +++ b/base/util.jl @@ -154,7 +154,7 @@ function julia_cmd(julia=joinpath(Sys.BINDIR::String, julia_exename())) elseif opts.check_bounds == 2 "no" # off else - "" # "default" + "" # default = "auto" end isempty(check_bounds) || push!(addflags, "--check-bounds=$check_bounds") end diff --git a/doc/man/julia.1 b/doc/man/julia.1 index 49ee30e0af90e..726e478362e4c 100644 --- a/doc/man/julia.1 +++ b/doc/man/julia.1 @@ -158,8 +158,8 @@ Set the level of debug info generation to Control whether inlining is permitted (overrides functions declared as @inline) .TP ---check-bounds={yes|no} -Emit bounds checks always or never (ignoring declarations) +--check-bounds={yes|no|auto} +Emit bounds checks always, never, or respect @inbounds declarations .TP --math-mode={ieee|user} diff --git a/doc/src/devdocs/boundscheck.md b/doc/src/devdocs/boundscheck.md index a9fb3baaae447..c4894469e4092 100644 --- a/doc/src/devdocs/boundscheck.md +++ b/doc/src/devdocs/boundscheck.md @@ -89,3 +89,7 @@ Note this hierarchy has been designed to reduce the likelihood of method ambigui to make `checkbounds` the place to specialize on array type, and try to avoid specializations on index types; conversely, `checkindex` is intended to be specialized only on index type (especially, the last argument). + +## Emit bounds checks + +Julia can be launched with `--check-bounds={yes|no|auto}` to emit bounds checks always, never, or respect @inbounds declarations. diff --git a/doc/src/manual/command-line-options.md b/doc/src/manual/command-line-options.md index b6dd1b6b02722..0efef2fa14ca2 100644 --- a/doc/src/manual/command-line-options.md +++ b/doc/src/manual/command-line-options.md @@ -30,7 +30,7 @@ The following is a complete list of command-line switches available when launchi |`-O`, `--optimize={0,1,2,3}` |Set the optimization level (default level is 2 if unspecified or 3 if used without a level)| |`-g`, `-g ` |Enable / Set the level of debug info generation (default level is 1 if unspecified or 2 if used without a level)| |`--inline={yes\|no}` |Control whether inlining is permitted, including overriding `@inline` declarations| -|`--check-bounds={yes\|no}` |Emit bounds checks always or never (ignoring declarations)| +|`--check-bounds={yes\|no\|auto}` |Emit bounds checks always, never, or respect @inbounds declarations| |`--math-mode={ieee,fast}` |Disallow or enable unsafe floating point optimizations (overrides @fastmath declaration)| |`--code-coverage={none\|user\|all}` |Count executions of source lines| |`--code-coverage` |equivalent to `--code-coverage=user`| diff --git a/src/jloptions.c b/src/jloptions.c index 92affe7679098..1beea6f30f5c3 100644 --- a/src/jloptions.c +++ b/src/jloptions.c @@ -129,7 +129,8 @@ static const char opts[] = " (default level is 1 if unspecified or 2 if used without a level)\n" #endif " --inline={yes|no} Control whether inlining is permitted, including overriding @inline declarations\n" - " --check-bounds={yes|no} Emit bounds checks always or never (ignoring declarations)\n" + " --check-bounds={yes|no|auto}\n" + " Emit bounds checks always, never, or respect @inbounds declarations\n" #ifdef USE_POLLY " --polly={yes|no} Enable or disable the polyhedral optimizer Polly (overrides @polly declaration)\n" #endif @@ -544,8 +545,10 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp) jl_options.check_bounds = JL_OPTIONS_CHECK_BOUNDS_ON; else if (!strcmp(optarg,"no")) jl_options.check_bounds = JL_OPTIONS_CHECK_BOUNDS_OFF; + else if (!strcmp(optarg,"auto")) + jl_options.check_bounds = JL_OPTIONS_CHECK_BOUNDS_DEFAULT; else - jl_errorf("julia: invalid argument to --check-bounds={yes|no} (%s)", optarg); + jl_errorf("julia: invalid argument to --check-bounds={yes|no|auto} (%s)", optarg); break; case opt_output_bc: jl_options.outputbc = optarg; diff --git a/test/cmdlineargs.jl b/test/cmdlineargs.jl index 6b600ad40f934..4c69bce4253f8 100644 --- a/test/cmdlineargs.jl +++ b/test/cmdlineargs.jl @@ -378,6 +378,8 @@ let exename = `$(Base.julia_cmd()) --startup-file=no` filter!(a -> !startswith(a, "--check-bounds="), exename_default_checkbounds.exec) @test parse(Int, readchomp(`$exename_default_checkbounds -E "Int(Base.JLOptions().check_bounds)"`)) == JL_OPTIONS_CHECK_BOUNDS_DEFAULT + @test parse(Int, readchomp(`$exename -E "Int(Base.JLOptions().check_bounds)" + --check-bounds=auto`)) == JL_OPTIONS_CHECK_BOUNDS_DEFAULT @test parse(Int, readchomp(`$exename -E "Int(Base.JLOptions().check_bounds)" --check-bounds=yes`)) == JL_OPTIONS_CHECK_BOUNDS_ON @test parse(Int, readchomp(`$exename -E "Int(Base.JLOptions().check_bounds)"