From e4e5d08621137473674cf3cdce0b36a43a8d6d15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Wed, 22 Aug 2012 14:54:45 +0200 Subject: compiler: Warn if the size of a binary segment is invalid The compiler would silently accept and Dialyzer would crash on code like: <> It is never acceptable for Dialyzer to crash. The compiler should at least generate a warning for such code. It is tempting to let the compiler generate an error, but that would mean that code like: Sz = 42.0, <>. would be possible to compile with optimizations disabled, but not with optimizations enabled. Dialyzer crashes because it calls cerl:bitstr_bitsize/1, which crashes if the type of size for the segment is invalid. The easiest way to avoid that crash is to extend the sanity checks in v3_core to also include the size field of binary segments. That will cause the compiler to issue a warning and to replace the bad binary construction with a call to erlang:error/1. (It also means that Dialyzer will not issue a warning for bad size fields.) --- lib/compiler/src/v3_kernel.erl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'lib/compiler/src/v3_kernel.erl') 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), -- cgit v1.2.3