diff options
author | Björn Gustavsson <[email protected]> | 2015-04-23 16:14:58 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2015-04-29 12:23:42 +0200 |
commit | d44be2bdc194e7c0afbf6fbd1de998aff097f030 (patch) | |
tree | ad616ec8a90b24bb060b9bf69a9f5343a532e57e /lib | |
parent | 808e43007754cb68dbe947ec6752698167b1c470 (diff) | |
download | otp-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.erl | 25 | ||||
-rw-r--r-- | lib/compiler/test/warnings_SUITE.erl | 6 |
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. ">>, [], []}], |