d: Don't generate code that throws exceptions when compiling with `-fno-exceptions'

The version flags for RTMI, RTTI, and exceptions was unconditionally
predefined.  These are now only predefined if the feature flag is
enabled.  It was noticed that there was no `-fexceptions' definition
inside d/lang.opt, so the detection of the exceptions option flag was
only partially working.  Once that was fixed, a few places in the
front-end implementation were found to fall fowl of `nothrow' rules,
these have been fixed upstream and backported here as well.

Reviewed-on: https://github.com/dlang/dmd/pull/15357
	     https://github.com/dlang/dmd/pull/15360

	PR d/110471

gcc/d/ChangeLog:

	* d-builtins.cc (d_init_versions): Predefine D_ModuleInfo,
	D_Exceptions, and D_TypeInfo only if feature is enabled.
	* lang.opt: Add -fexceptions.

gcc/testsuite/ChangeLog:

	* gdc.dg/pr110471a.d: New test.
	* gdc.dg/pr110471b.d: New test.
	* gdc.dg/pr110471c.d: New test.

(cherry picked from commit da108c75ad386b3f1f47abb2265296e4b61d578a)
This commit is contained in:
Iain Buclaw 2023-07-01 17:01:30 +02:00
parent 23c64450cb
commit 6e7909191a
8 changed files with 28 additions and 7 deletions

View File

@ -500,9 +500,12 @@ d_init_versions (void)
VersionCondition::addPredefinedGlobalIdent ("D_BetterC");
else
{
VersionCondition::addPredefinedGlobalIdent ("D_ModuleInfo");
VersionCondition::addPredefinedGlobalIdent ("D_Exceptions");
VersionCondition::addPredefinedGlobalIdent ("D_TypeInfo");
if (global.params.useModuleInfo)
VersionCondition::addPredefinedGlobalIdent ("D_ModuleInfo");
if (global.params.useExceptions)
VersionCondition::addPredefinedGlobalIdent ("D_Exceptions");
if (global.params.useTypeInfo)
VersionCondition::addPredefinedGlobalIdent ("D_TypeInfo");
}
if (optimize)

View File

@ -574,7 +574,7 @@ unittest
private template arraySortWrapper(T, alias fn)
{
pragma(mangle, "arraySortWrapper_" ~ T.mangleof ~ "_" ~ fn.mangleof)
extern(C) int arraySortWrapper(scope const void* e1, scope const void* e2) nothrow
extern(C) int arraySortWrapper(scope const void* e1, scope const void* e2)
{
return fn(cast(const(T*))e1, cast(const(T*))e2);
}

View File

@ -807,9 +807,8 @@ private void doGNUABITagSemantic(ref Expression e, ref Expression* lastTag)
// but it's a concession to practicality.
// Casts are unfortunately necessary as `implicitConvTo` is not
// `const` (and nor is `StringExp`, by extension).
static int predicate(const scope Expression* e1, const scope Expression* e2) nothrow
static int predicate(const scope Expression* e1, const scope Expression* e2)
{
scope(failure) assert(0, "An exception was thrown");
return (cast(Expression*)e1).toStringExp().compare((cast(Expression*)e2).toStringExp());
}
ale.elements.sort!predicate;

View File

@ -1420,7 +1420,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
* https://issues.dlang.org/show_bug.cgi?id=14246
*/
AggregateDeclaration ad = ctor.isMemberDecl();
if (!ctor.fbody || !ad || !ad.fieldDtor || !global.params.dtorFields || global.params.betterC || ctor.type.toTypeFunction.isnothrow)
if (!ctor.fbody || !ad || !ad.fieldDtor || !global.params.dtorFields || !global.params.useExceptions || ctor.type.toTypeFunction.isnothrow)
return visit(cast(FuncDeclaration)ctor);
/* Generate:

View File

@ -291,6 +291,10 @@ fdump-d-original
D
Display the frontend AST after parsing and semantic passes.
fexceptions
D
; Documented in common.opt
fextern-std=
D Joined RejectNegative Enum(extern_stdcpp) Var(flag_extern_stdcpp)
-fextern-std=<standard> Set C++ name mangling compatibility with <standard>.

View File

@ -0,0 +1,5 @@
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110471
// { dg-do compile }
// { dg-options "-fno-exceptions" }
version (D_Exceptions)
static assert(0);

View File

@ -0,0 +1,5 @@
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110471
// { dg-do compile }
// { dg-options "-fno-moduleinfo" }
version (D_ModuleInfo)
static assert(0);

View File

@ -0,0 +1,5 @@
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=110471
// { dg-do compile }
// { dg-options "-fno-rtti" }
version (D_TypeInfo)
static assert(0);