From d44be2bdc194e7c0afbf6fbd1de998aff097f030 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Thu, 23 Apr 2015 16:14:58 +0200 Subject: 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. --- lib/compiler/src/sys_core_fold.erl | 25 +++++++++++++++++++++---- lib/compiler/test/warnings_SUITE.erl | 6 ++++++ 2 files changed, 27 insertions(+), 4 deletions(-) (limited to 'lib') 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. ">>, [], []}], -- cgit v1.2.3