diff options
author | Björn Gustavsson <[email protected]> | 2012-08-23 09:58:17 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2012-08-23 09:58:17 +0200 |
commit | e7720fe2b2a1f09af70e74b54442f72f84609a31 (patch) | |
tree | d4fc0f35f41d9c9e1674af29510e797a118220fc /lib | |
parent | e479ebeb58beaa8261fa90e54681dc30e5ee3085 (diff) | |
parent | e4e5d08621137473674cf3cdce0b36a43a8d6d15 (diff) | |
download | otp-e7720fe2b2a1f09af70e74b54442f72f84609a31.tar.gz otp-e7720fe2b2a1f09af70e74b54442f72f84609a31.tar.bz2 otp-e7720fe2b2a1f09af70e74b54442f72f84609a31.zip |
Merge branch 'bjorn/compiler/illegal-size/OTP-10197' into maint
* bjorn/compiler/illegal-size/OTP-10197:
compiler: Warn if the size of a binary segment is invalid
Diffstat (limited to 'lib')
-rw-r--r-- | lib/compiler/src/v3_core.erl | 7 | ||||
-rw-r--r-- | lib/compiler/src/v3_kernel.erl | 7 | ||||
-rw-r--r-- | lib/compiler/test/bs_construct_SUITE.erl | 4 |
3 files changed, 16 insertions, 2 deletions
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl index 242196c593..01042cc56f 100644 --- a/lib/compiler/src/v3_core.erl +++ b/lib/compiler/src/v3_core.erl @@ -823,6 +823,13 @@ bitstr({bin_element,_,E0,Size0,[Type,{unit,Unit}|Flags]}, St0) -> {_,_} -> throw(bad_binary) end, + case Size1 of + #c_var{} -> ok; + #c_literal{val=Sz} when is_integer(Sz), Sz >= 0 -> ok; + #c_literal{val=undefined} -> ok; + #c_literal{val=all} -> ok; + _ -> throw(bad_binary) + end, {#c_bitstr{val=E1,size=Size1, unit=#c_literal{val=Unit}, type=#c_literal{val=Type}, diff --git a/lib/compiler/src/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl index c4e7b45aac..b184987625 100644 --- a/lib/compiler/src/v3_kernel.erl +++ b/lib/compiler/src/v3_kernel.erl @@ -278,11 +278,12 @@ expr(#c_binary{anno=A,segments=Cv}, Sub, St0) -> {#k_binary{anno=A,segs=Kv},Ep,St1} catch throw:bad_element_size -> + St1 = add_warning(get_line(A), bad_segment_size, A, St0), Erl = #c_literal{val=erlang}, Name = #c_literal{val=error}, Args = [#c_literal{val=badarg}], Error = #c_call{anno=A,module=Erl,name=Name,args=Args}, - expr(Error, Sub, St0) + expr(Error, Sub, St1) end; expr(#c_fun{anno=A,vars=Cvs,body=Cb}, Sub0, #kern{ff=OldFF,func=Func}=St0) -> FA = case OldFF of @@ -1827,7 +1828,9 @@ format_error({nomatch_shadow,Line}) -> format_error(nomatch_shadow) -> "this clause cannot match because a previous clause always matches"; format_error(bad_call) -> - "invalid module and/or function name; this call will always fail". + "invalid module and/or function name; this call will always fail"; +format_error(bad_segment_size) -> + "binary construction will fail because of a type mismatch". add_warning(none, Term, Anno, #kern{ws=Ws}=St) -> File = get_file(Anno), diff --git a/lib/compiler/test/bs_construct_SUITE.erl b/lib/compiler/test/bs_construct_SUITE.erl index 31c7890f26..e8b30f44ce 100644 --- a/lib/compiler/test/bs_construct_SUITE.erl +++ b/lib/compiler/test/bs_construct_SUITE.erl @@ -468,6 +468,10 @@ opt(Config) when is_list(Config) -> ?line {'EXIT',_} = (catch <<<<23,56,0,2>>:64/float>>), ?line {'EXIT',_} = (catch <<<<23,56,0,2:7>>/binary>>), + %% Test constant propagation - there should be a warning. + BadSz = 2.5, + {'EXIT',_} = (catch <<<<N,56,0,2>>:BadSz/binary>>), + case id(false) of true -> ?line opt_dont_call_me(); false -> ok |