STR-761: SEGV from all(...) applied to annotated list.
The following code will cause a SEGV.
!["A"]{0} ; all(fail) /* does SEGV */
The following will not.
!["A"] ; all(fail) /* does not SEGV */I believe this is a problem in ../strategoxt-0.17pre18253/stratego-libraries/runtime/lib/stratego.c. We changed the code to the following - this might not be the right fix though.
ATerm SRTS_all(StrSL sl, StrCL f, ATerm t)
Submitted on 26 November 2008 at 20:38
{
ATerm annos = ATgetAnnotations(t);
switch(ATgetType(t))
{
case AT_APPL :
{
Symbol c = ATgetSymbol((ATermAppl) t);
int i, arity = ATgetArity(c), changed = 0;
ATerm kids[arity], original, new;
for(i = 0; i < arity; i++)
{
original = ATgetArgument(t, i);
new = cl_fun(f)(cl_sl(f),original);
if(new == NULL)
return NULL;
kids[i] = new;
if(original != new) changed++;
}
if(changed)
t = (ATerm) ATmakeApplArray(c, kids);
}
break;
case AT_LIST :
if(!ATisEmpty(t))
{
// ATL:FIX artf5648
//
ATerm tmp = (ATerm)ATmap((ATermList) t, f);
if(tmp) t = tmp;
//
// ATL:FIX end
}
break;
}
if(annos == NULL)
return t;
else
return(ATsetAnnotations(t, annos));
}
Issue Log
STR-761, martin:
I cannot check it right now, but this does indeed look like the right fix to me.We’ll write a test for the future and apply your fix.
Thanks for reporting!
STR-761, dwaddington:
Hmm, actually my original fix seems to be wrong. Here is the new fix (I think) which I am testing./**
* Traversal combinators
*/
ATerm SRTS_all(StrSL sl, StrCL f, ATerm t)
{
ATerm annos = ATgetAnnotations(t);
switch(ATgetType(t))
{
case AT_APPL :
{
Symbol c = ATgetSymbol((ATermAppl) t);
int i, arity = ATgetArity(c), changed = 0;
ATerm kids[arity], original, new;
for(i = 0; i < arity; i++)
{
original = ATgetArgument(t, i);
new = cl_fun(f)(cl_sl(f),original);
if(new == NULL)
return NULL;
kids[i] = new;
if(original != new) changed++;
}
if(changed)
t = (ATerm) ATmakeApplArray(c, kids);
}
break;
case AT_LIST :
if(!ATisEmpty(t))
{
t = (ATerm)ATmap((ATermList) t, f);
}
break;
}// ATL:FIX STR-761
//
if(annos == NULL)
return t;
else {
if(t)
return(ATsetAnnotations(t, annos));
else
return t;
}
//
// END ATL:FIX
}ATerm SRTS_one(StrSL sl, StrCL f, ATerm t)
{
ATerm annos = ATgetAnnotations(t);
//ATfprintf(stderr, "_one(%t)
", t);
switch(ATgetType(t)) {
case AT_APPL :
{
int i, arity = ATgetArity(ATgetSymbol((ATermAppl) t)), transformed = 0;
for(i = 0; i < arity; i++)
{
ATerm original, new;
original = ATgetArgument(t, i);
new = cl_fun(f)(cl_sl(f),original);
if(new == NULL)
continue;
transformed++;
if(new != original)
t = (ATerm)ATsetArgument((ATermAppl) t, new, i);
break;
}
if(!transformed)
return NULL;
}
break;
case AT_LIST :
{
ATermList prefix = ATempty;
ATermList suffix = (ATermList) t;
int transformed = 0;
while(!ATisEmpty(suffix))
{
ATerm original = ATgetFirst(suffix);
ATerm new = cl_fun(f)(cl_sl(f),original);
suffix = ATgetNext(suffix);
if(new == NULL)
{
prefix = ATinsert(prefix, original);
continue;
}
transformed++;
if(new == original)
suffix = (ATermList) t;
else
{
suffix = ATinsert(suffix, new);
while(!ATisEmpty(prefix)) {
suffix = ATinsert(suffix, ATgetFirst(prefix));
prefix = ATgetNext(prefix);
}
}
// ATfprintf(stderr, "_one: %t
", suffix);
t = (ATerm) suffix;
break;
}
if(!transformed)
return NULL;
}
break;
default:
return NULL;
}// ATL:FIX STR-761
//
if(annos == NULL)
return t;
else {
if(t)
return(ATsetAnnotations(t, annos));
else
return t;
}
//
// END ATL:FIX}
STR-761, karltk:
Fixed for SRTS_all/some/one. Added unit test to avoid regression. Optimized the suggested condition checking a bit.
Log in to post comments