Skip to content

Commit

Permalink
Merge pull request dabeaz#168 from laerreal/fixup_infinite_recursion
Browse files Browse the repository at this point in the history
Fixup infinite recursion in CPP during macro arguments expansion
  • Loading branch information
dabeaz authored Dec 22, 2018
2 parents 2750294 + 8ad324d commit eccf10c
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 6 deletions.
12 changes: 6 additions & 6 deletions ply/cpp.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ def macro_prescan(self,macro):
# representing the replacement macro tokens
# ----------------------------------------------------------------------

def macro_expand_args(self,macro,args):
def macro_expand_args(self,macro,args,expanded):
# Make a copy of the macro token sequence
rep = [copy.copy(_x) for _x in macro.value]

Expand All @@ -460,16 +460,16 @@ def macro_expand_args(self,macro,args):
# has been sorted in reverse order of patch location since replacements will cause the
# size of the replacement sequence to expand from the patch point.

expanded = { }
expanded_args = { }
for ptype, argnum, i in macro.patch:
# Concatenation. Argument is left unexpanded
if ptype == 'c':
rep[i:i+1] = args[argnum]
# Normal expansion. Argument is macro expanded first
elif ptype == 'e':
if argnum not in expanded:
expanded[argnum] = self.expand_macros(args[argnum])
rep[i:i+1] = expanded[argnum]
if argnum not in expanded_args:
expanded_args[argnum] = self.expand_macros(args[argnum],expanded)
rep[i:i+1] = expanded_args[argnum]

# Get rid of removed comma if necessary
if comma_patch:
Expand Down Expand Up @@ -530,7 +530,7 @@ def expand_macros(self,tokens,expanded=None):
del args[len(m.arglist):]

# Get macro replacement text
rep = self.macro_expand_args(m,args)
rep = self.macro_expand_args(m,args,expanded)
rep = self.expand_macros(rep,expanded)
for r in rep:
r.lineno = t.lineno
Expand Down
16 changes: 16 additions & 0 deletions test/testcpp.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,22 @@ def __test_preprocessing(self, in_, expected, time_limit = 1.0):
else:
self.assertMultiLineEqual(out, expected)

def test_infinite_argument_expansion(self):
# CPP does not drags set of currently expanded macros through macro
# arguments expansion. If there is a match between an argument value
# and name of an already expanded macro then CPP falls into infinite
# recursion.
self.__test_preprocessing("""\
#define a(x) x
#define b a(b)
b
""" , """\
b"""
)


def test_concatenation(self):
self.__test_preprocessing("""\
#define a(x) x##_
Expand Down

0 comments on commit eccf10c

Please sign in to comment.