From b3bee03e513c5a3d777c6df360a2f421ba1cc610 Mon Sep 17 00:00:00 2001
From: Hans Bolinder <hasse@erlang.org>
Date: Thu, 20 Feb 2014 13:01:32 +0100
Subject: Fix a bug in epp concerning circular macro definitions

epp could loop when encountering a circular macro definition in an
included file.

Thanks to Maruthavanan Subbarayan for reporting the bug, and to
Richard Carlsson for providing a bug fix.
---
 lib/stdlib/src/epp.erl        |  4 ++--
 lib/stdlib/test/epp_SUITE.erl | 32 +++++++++++++++++++++++++++++---
 2 files changed, 31 insertions(+), 5 deletions(-)

(limited to 'lib')

diff --git a/lib/stdlib/src/epp.erl b/lib/stdlib/src/epp.erl
index 4fd302e612..dc25b6b9f4 100644
--- a/lib/stdlib/src/epp.erl
+++ b/lib/stdlib/src/epp.erl
@@ -1,7 +1,7 @@
 %%
 %% %CopyrightBegin%
 %%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
 %%
 %% The contents of this file are subject to the Erlang Public License,
 %% Version 1.1, (the "License"); you may not use this file except in
@@ -640,7 +640,7 @@ leave_file(From, St) ->
 		    Ms = dict:store({atom,'FILE'},
 				    {none,[{string,CurrLoc,OldName2}]},
 				    St#epp.macs),
-                    NextSt = OldSt#epp{sstk=Sts,macs=Ms},
+                    NextSt = OldSt#epp{sstk=Sts,macs=Ms,uses=St#epp.uses},
 		    enter_file_reply(From, OldName, CurrLoc, CurrLoc),
                     case OldName2 =:= OldName of
                         true ->
diff --git a/lib/stdlib/test/epp_SUITE.erl b/lib/stdlib/test/epp_SUITE.erl
index 0cbdf76270..0b4726c07a 100644
--- a/lib/stdlib/test/epp_SUITE.erl
+++ b/lib/stdlib/test/epp_SUITE.erl
@@ -1,7 +1,7 @@
 %%
 %% %CopyrightBegin%
 %%
-%% Copyright Ericsson AB 1998-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2014. All Rights Reserved.
 %%
 %% The contents of this file are subject to the Erlang Public License,
 %% Version 1.1, (the "License"); you may not use this file except in
@@ -25,7 +25,8 @@
 	 variable_1/1, otp_4870/1, otp_4871/1, otp_5362/1,
          pmod/1, not_circular/1, skip_header/1, otp_6277/1, otp_7702/1,
          otp_8130/1, overload_mac/1, otp_8388/1, otp_8470/1, otp_8503/1,
-         otp_8562/1, otp_8665/1, otp_8911/1, otp_10302/1, otp_10820/1]).
+         otp_8562/1, otp_8665/1, otp_8911/1, otp_10302/1, otp_10820/1,
+         otp_11728/1]).
 
 -export([epp_parse_erl_form/2]).
 
@@ -67,7 +68,7 @@ all() ->
      {group, variable}, otp_4870, otp_4871, otp_5362, pmod,
      not_circular, skip_header, otp_6277, otp_7702, otp_8130,
      overload_mac, otp_8388, otp_8470, otp_8503, otp_8562,
-     otp_8665, otp_8911, otp_10302, otp_10820].
+     otp_8665, otp_8911, otp_10302, otp_10820, otp_11728].
 
 groups() -> 
     [{upcase_mac, [], [upcase_mac_1, upcase_mac_2]},
@@ -1387,6 +1388,31 @@ do_otp_10820(File, C, PC) ->
     true = test_server:stop_node(Node),
     ok.
 
+otp_11728(doc) ->
+    ["OTP-11728. Bugfix circular macro."];
+otp_11728(suite) ->
+    [];
+otp_11728(Config) when is_list(Config) ->
+    Dir = ?config(priv_dir, Config),
+    H = <<"-define(MACRO,[[]++?MACRO]).">>,
+    HrlFile = filename:join(Dir, "otp_11728.hrl"),
+    ok = file:write_file(HrlFile, H),
+    C = <<"-module(otp_11728).
+           -compile(export_all).
+
+           -include(\"otp_11728.hrl\").
+
+           function_name()->
+               A=?MACRO, % line 7
+               ok">>,
+    ErlFile = filename:join(Dir, "otp_11728.erl"),
+    ok = file:write_file(ErlFile, C),
+    {ok, L} = epp:parse_file(ErlFile, [Dir], []),
+    true = lists:member({error,{7,epp,{circular,'MACRO',none}}}, L),
+    _ = file:delete(HrlFile),
+    _ = file:delete(ErlFile),
+    ok.
+
 check(Config, Tests) ->
     eval_tests(Config, fun check_test/2, Tests).
 
-- 
cgit v1.2.3