diff options
author | Björn Gustavsson <[email protected]> | 2015-05-12 06:34:54 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2015-05-13 15:05:00 +0200 |
commit | c758fa81e1c48c56ff20ef2a95e6424c1e69033a (patch) | |
tree | 6ba7b0fcc44fe4896a690ecaa18db72a9fe47169 | |
parent | 6a3e878126da1e8d75c704510c7a7339ff306138 (diff) | |
download | otp-c758fa81e1c48c56ff20ef2a95e6424c1e69033a.tar.gz otp-c758fa81e1c48c56ff20ef2a95e6424c1e69033a.tar.bz2 otp-c758fa81e1c48c56ff20ef2a95e6424c1e69033a.zip |
sys_core_fold: Eliminate warnings for unused terms
The optimization introduced in 0a0d39d351fc would cause spurious
warnings of the type: "a term is constructed, but never used".
To avoid the warning, we must mark not only tuples and lists as
compiler_generated, but also each element. We must also propagate
compiler_generated annotations in lets. For example, if we have:
let <X -| ['compiler_generated']> = 42 in X + 1
we must propagate the compiler_generated annotation to the literal
when do constant propagation:
42 -| ['compiler_generated'] + 1
-rw-r--r-- | lib/compiler/src/sys_core_fold.erl | 27 | ||||
-rw-r--r-- | lib/compiler/test/warnings_SUITE.erl | 8 |
2 files changed, 28 insertions, 7 deletions
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl index 6f8279f65e..4068d60ec4 100644 --- a/lib/compiler/src/sys_core_fold.erl +++ b/lib/compiler/src/sys_core_fold.erl @@ -1130,11 +1130,23 @@ let_substs_1(Vs, #c_values{es=As}, Sub) -> let_substs_1([V], A, Sub) -> let_subst_list([V], [A], Sub); let_substs_1(Vs, A, _) -> {Vs,A,[]}. -let_subst_list([V|Vs0], [A|As0], Sub) -> +let_subst_list([V|Vs0], [A0|As0], Sub) -> {Vs1,As1,Ss} = let_subst_list(Vs0, As0, Sub), - case is_subst(A) of - true -> {Vs1,As1,sub_subst_var(V, A, Sub) ++ Ss}; - false -> {[V|Vs1],[A|As1],Ss} + case is_subst(A0) of + true -> + A = case is_compiler_generated(V) andalso + not is_compiler_generated(A0) of + true -> + %% Propagate the 'compiler_generated' annotation + %% along with the value. + Ann = [compiler_generated|cerl:get_ann(A0)], + cerl:set_ann(A0, Ann); + false -> + A0 + end, + {Vs1,As1,sub_subst_var(V, A, Sub) ++ Ss}; + false -> + {[V|Vs1],[A0|As1],Ss} end; let_subst_list([], [], _) -> {[],[],[]}. @@ -1899,8 +1911,8 @@ case_data_pat_alias(P, BindTo0, TypeSig, Bs0) -> %% Here we will need to actually build the data and bind %% it to the variable. {Type,Arity} = TypeSig, - Vars = make_vars([], Arity), Ann = [compiler_generated], + Vars = make_vars(Ann, Arity), Data = cerl:ann_make_data(Ann, Type, Vars), Bs = [{BindTo0,P},{P,Data}|Bs0], {Vars,Bs}; @@ -2392,8 +2404,9 @@ delay_build_1(Core0, TypeSig) -> try delay_build_expr(Core0, TypeSig) of Core -> {Type,Arity} = TypeSig, - Vars = make_vars([], Arity), - Data = cerl:ann_make_data([compiler_generated], Type, Vars), + Ann = [compiler_generated], + Vars = make_vars(Ann, Arity), + Data = cerl:ann_make_data(Ann, Type, Vars), {yes,Vars,Core,Data} catch throw:impossible -> diff --git a/lib/compiler/test/warnings_SUITE.erl b/lib/compiler/test/warnings_SUITE.erl index f6ba75577d..471ded219f 100644 --- a/lib/compiler/test/warnings_SUITE.erl +++ b/lib/compiler/test/warnings_SUITE.erl @@ -739,6 +739,14 @@ no_warnings(Config) when is_list(Config) -> case R0 of {r,V1,_V2,V3} -> {r,V1,\"def\",V3} end. + + d(In0, Bool) -> + {In1,Int} = case id(Bool) of + false -> {In0,0} + end, + [In1,Int]. + + id(I) -> I. ">>, [], []}], |