Bug 12979 – Nothrow violation error is hidden by inline assembler

Status
RESOLVED
Resolution
FIXED
Severity
critical
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-06-24T05:22:00Z
Last change time
2015-02-18T03:37:51Z
Keywords
accepts-invalid
Assigned to
nobody
Creator
k.hara.pg
Blocks
10520, 11471, 13530

Comments

Comment #0 by k.hara.pg — 2014-06-24T05:22:39Z
Test case: void main() nothrow { throw new Exception(""); version(A) asm { nop; } } Without -version=A, the error "Exception is thrown but not caught" is properly reported. But with -version=A, no error occurs.
Comment #1 by k.hara.pg — 2014-06-29T06:19:25Z
Copy my comment from https://issues.dlang.org/show_bug.cgi?id=11471#c6 ----- The root issue is in FuncDeclaration::semantic3. ... else if (hasReturnExp & 8) // if inline asm { flags &= ~FUNCFLAGnothrowInprocess; } else { // Check for errors related to 'nothrow'. unsigned int nothrowErrors = global.errors; int blockexit = fbody->blockExit(this, f->isnothrow); if (f->isnothrow && (global.errors != nothrowErrors) ) ::error(loc, "%s '%s' is nothrow yet may throw", kind(), toPrettyChars()); ... In front-end, if a function body has inline asm statements, the function's nothrow check is skipped! But many functions in druntime rely on the loose behavior currently.
Comment #2 by ibuclaw — 2014-09-24T22:17:53Z
Comment #3 by ibuclaw — 2014-09-24T22:21:25Z
There seems to be a contradiction in the semantic passes too. Having an asm statement in a nothrow function is both valid and an error. https://github.com/D-Programming-Language/dmd/blob/master/src/func.c#L1778 https://github.com/D-Programming-Language/dmd/blob/master/src/statement.c#L695
Comment #4 by k.hara.pg — 2014-09-29T02:03:50Z
Finally I thought that the following semantic would be pragmatic. By default, inline assembler statement is handled as impure, unsafe, throwable, and gc-able. void f()() { asm { nop; } } pragma(msg, typeof(&f!())); // will print 'void function() @system' But, explicit annotating with 'pure', 'nothrow', '@trusted', and '@nogc' will be able to override the behavior. void f2()() pure nothrow @trusted @nogc { asm { nop; } } pragma(msg, typeof(&f2!())); // will print 'void function() pure nothrow @trusted @nogc' And still, inline assembler is unsafe, so it will conflict wiht '@safe' attribute. void f3()() @safe { asm { nop; } } pragma(msg, typeof(&f3!())); // Error: inline assembler not allowed in @safe function f!().f
Comment #5 by github-bugzilla — 2014-10-06T13:05:31Z
Commits pushed to master at https://github.com/D-Programming-Language/dmd https://github.com/D-Programming-Language/dmd/commit/31b8ff1d0b5fb692313cbe1a04578304eb5e924d fix Issue 12979 - Nothrow violation error is hidden by inline assembler - deprecate using unattributed asm in attributed functions - add explicit attributes on asm statments (unverified by compiler) asm pure nothrow @nogc @trusted { //... } - added new CompoundAsmStatement because the parser already splits asm blocks into many AsmStatements https://github.com/D-Programming-Language/dmd/commit/a1ec5c71600cbe62218476d605aa2aa624da044c Merge pull request #4033 from MartinNowak/fix12979 fix Issue 12979 - Nothrow violation error is hidden by inline assembler
Comment #6 by github-bugzilla — 2015-02-18T03:37:51Z