Skip to content

Loading…

Issue 9309 - Regression (2.061): -O -release generates wrong code #1474

Merged
merged 1 commit into from

3 participants

@9rnsr
D Programming Language member

http://d.puremagic.com/issues/show_bug.cgi?id=9309

By merging pull #1110, escapeShellArgument!allocator is marked as PUREstrong.
But it is a nested function, and its call may have a side effect through
its hidden context pointer. So glue layer cannot remove its call.

@yebblies
D Programming Language member

How can it be strongly pure if it has mutable state accessible through the context pointer?

@9rnsr
D Programming Language member

Ah..., right. The root problem is in FuncDeclaration::isPure, it does not check fd->isNested().
In current, all nested functions should be weak purity at most.

@9rnsr 9rnsr closed this
@9rnsr 9rnsr fix Issue 9309 - Regression (2.061): -O -release generates wrong code
In current, all nested functions should be weak purity at most.
a337375
@9rnsr 9rnsr reopened this
@9rnsr
D Programming Language member

Updated.

@WalterBright WalterBright merged commit 7686d93 into D-Programming-Language:master

1 check passed

Details default Pass: 10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 13, 2013
  1. @9rnsr

    fix Issue 9309 - Regression (2.061): -O -release generates wrong code

    9rnsr committed
    In current, all nested functions should be weak purity at most.
Showing with 39 additions and 0 deletions.
  1. +2 −0 src/func.c
  2. +37 −0 test/runnable/test9309.d
View
2 src/func.c
@@ -2985,6 +2985,8 @@ enum PURE FuncDeclaration::isPure()
if (tf->purity == PUREfwdref)
tf->purityLevel();
enum PURE purity = tf->purity;
+ if (purity > PUREweak && isNested())
+ purity = PUREweak;
if (purity > PUREweak && needThis())
{ // The attribute of the 'this' reference affects purity strength
if (type->mod & (MODimmutable | MODwild))
View
37 test/runnable/test9309.d
@@ -0,0 +1,37 @@
+immutable(T)[] assumeUnique(T)(ref T[] array) pure nothrow
+{
+ auto result = cast(immutable(T)[]) array;
+ array = null;
+ return result;
+}
+
+pure nothrow
+private string escapeShellArguments()
+{
+ char[] buf;
+
+ @safe nothrow
+ char[] allocator(size_t size)
+ {
+ return buf = new char[size];
+ }
+
+ escapeShellArgument!allocator("foo");
+ return assumeUnique(buf);
+}
+
+@safe nothrow
+auto escapeShellArgument(alias allocator)(in char[] arg)
+{
+ auto buf = allocator(4);
+ buf[0] = 'f';
+ buf[1] = 'o';
+ buf[2] = 'o';
+ buf[3] = '\0';
+}
+
+void main()
+{
+ string res = escapeShellArguments();
+ if (res != "foo\0") assert(0);
+}
Something went wrong with that request. Please try again.