aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2015-04-23 16:14:58 +0200
committerBjörn Gustavsson <[email protected]>2015-04-29 12:23:42 +0200
commitd44be2bdc194e7c0afbf6fbd1de998aff097f030 (patch)
treead616ec8a90b24bb060b9bf69a9f5343a532e57e /lib
parent808e43007754cb68dbe947ec6752698167b1c470 (diff)
downloadotp-d44be2bdc194e7c0afbf6fbd1de998aff097f030.tar.gz
otp-d44be2bdc194e7c0afbf6fbd1de998aff097f030.tar.bz2
otp-d44be2bdc194e7c0afbf6fbd1de998aff097f030.zip
sys_core_fold: Suppress warnings better
86fbd6d76d strengthened type optimization in lets. As a result of the stronger optimizations, special care had to be taken to suppress false warnings. It turns out that false warnings can still slip through. Slapping on a 'compiler_generated' annotation at the top-level of a complex term such as #c_tuple{} may not suppress all warnings. We will need to go deeper into the term to eliminate all warnings.
Diffstat (limited to 'lib')
-rw-r--r--lib/compiler/src/sys_core_fold.erl25
-rw-r--r--lib/compiler/test/warnings_SUITE.erl6
2 files changed, 27 insertions, 4 deletions
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl
index beab2ce897..6f8279f65e 100644
--- a/lib/compiler/src/sys_core_fold.erl
+++ b/lib/compiler/src/sys_core_fold.erl
@@ -2532,18 +2532,35 @@ maybe_suppress_warnings(Arg, _, _, effect) ->
%% Don't suppress any warnings in effect context.
Arg;
maybe_suppress_warnings(Arg, Vs, PrevBody, value) ->
- case suppress_warning(Arg) of
+ case should_suppress_warning(Arg) of
true ->
Arg; %Already suppressed.
false ->
case is_any_var_used(Vs, PrevBody) of
true ->
- cerl:set_ann(Arg, [compiler_generated]);
+ suppress_warning([Arg]);
false ->
Arg
end
end.
+%% Suppress warnings for a Core Erlang expression whose value will
+%% be ignored.
+suppress_warning([H|T]) ->
+ case cerl:is_literal(H) of
+ true ->
+ suppress_warning(T);
+ false ->
+ case cerl:is_data(H) of
+ true ->
+ suppress_warning(cerl:data_es(H) ++ T);
+ false ->
+ Arg = cerl:set_ann(H, [compiler_generated]),
+ cerl:c_seq(Arg, suppress_warning(T))
+ end
+ end;
+suppress_warning([]) -> void().
+
move_case_into_arg(#c_case{arg=#c_let{vars=OuterVars0,arg=OuterArg,
body=InnerArg0}=Outer,
clauses=InnerClauses}=Inner, Sub) ->
@@ -3093,7 +3110,7 @@ add_bin_opt_info(Core, Term) ->
end.
add_warning(Core, Term) ->
- case suppress_warning(Core) of
+ case should_suppress_warning(Core) of
true ->
ok;
false ->
@@ -3118,7 +3135,7 @@ get_file([{file,File}|_]) -> File;
get_file([_|T]) -> get_file(T);
get_file([]) -> "no_file". % should not happen
-suppress_warning(Core) ->
+should_suppress_warning(Core) ->
is_compiler_generated(Core) orelse
is_result_unwanted(Core).
diff --git a/lib/compiler/test/warnings_SUITE.erl b/lib/compiler/test/warnings_SUITE.erl
index e996a55db6..f6ba75577d 100644
--- a/lib/compiler/test/warnings_SUITE.erl
+++ b/lib/compiler/test/warnings_SUITE.erl
@@ -733,6 +733,12 @@ no_warnings(Config) when is_list(Config) ->
false -> Var;
true -> []
end.
+
+ c() ->
+ R0 = {r,\"abc\",undefined,os:timestamp()}, %No warning.
+ case R0 of
+ {r,V1,_V2,V3} -> {r,V1,\"def\",V3}
+ end.
">>,
[],
[]}],