* [committed] d: Fix ICE using non-local variable: internal compiler error: Segmentation fault
@ 2020-08-03 10:00 Iain Buclaw
0 siblings, 0 replies; only message in thread
From: Iain Buclaw @ 2020-08-03 10:00 UTC (permalink / raw)
To: gcc-patches
Hi,
This patch moves no frame access error to own function, adding use of it
for both when get_framedecl() cannot find a path to the outer function
frame, and guarding get_decl_tree() from recursively calling itself.
Bootstrapped and regression tested on x86_64-linux-gnu with multilib
configurations -m32 and -mx32. Committed to mainline.
Regards
Iain
---
gcc/d/ChangeLog:
PR d/96254
* d-codegen.cc (error_no_frame_access): New.
(get_frame_for_symbol): Use fdparent name in error message.
(get_framedecl): Replace call to assert with error.
* d-tree.h (error_no_frame_access): Declare.
* decl.cc (get_decl_tree): Detect recursion and error.
gcc/testsuite/ChangeLog:
PR d/96254
* gdc.dg/pr96254a.d: New test.
* gdc.dg/pr96254b.d: New test.
---
gcc/d/d-codegen.cc | 53 +++++++++++++++++++--------------
gcc/d/d-tree.h | 1 +
gcc/d/decl.cc | 5 ++++
gcc/testsuite/gdc.dg/pr96254a.d | 28 +++++++++++++++++
gcc/testsuite/gdc.dg/pr96254b.d | 24 +++++++++++++++
5 files changed, 89 insertions(+), 22 deletions(-)
create mode 100644 gcc/testsuite/gdc.dg/pr96254a.d
create mode 100644 gcc/testsuite/gdc.dg/pr96254b.d
diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 2dce09d7187..296d62a91a4 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -2127,6 +2127,17 @@ build_vthis_function (tree basetype, tree type)
return fntype;
}
+/* Raise an error at that the context pointer of the function or object SYM is
+ not accessible from the current scope. */
+
+tree
+error_no_frame_access (Dsymbol *sym)
+{
+ error_at (input_location, "cannot get frame pointer to %qs",
+ sym->toPrettyChars ());
+ return null_pointer_node;
+}
+
/* If SYM is a nested function, return the static chain to be
used when calling that function from the current function.
@@ -2191,7 +2202,7 @@ get_frame_for_symbol (Dsymbol *sym)
{
error_at (make_location_t (sym->loc),
"%qs is a nested function and cannot be accessed from %qs",
- fd->toPrettyChars (), thisfd->toPrettyChars ());
+ fdparent->toPrettyChars (), thisfd->toPrettyChars ());
return null_pointer_node;
}
@@ -2202,39 +2213,35 @@ get_frame_for_symbol (Dsymbol *sym)
while (fd != dsym)
{
/* Check if enclosing function is a function. */
- FuncDeclaration *fd = dsym->isFuncDeclaration ();
+ FuncDeclaration *fdp = dsym->isFuncDeclaration ();
+ Dsymbol *parent = dsym->toParent2 ();
- if (fd != NULL)
+ if (fdp != NULL)
{
- if (fdparent == fd->toParent2 ())
+ if (fdparent == parent)
break;
- gcc_assert (fd->isNested () || fd->vthis);
- dsym = dsym->toParent2 ();
+ gcc_assert (fdp->isNested () || fdp->vthis);
+ dsym = parent;
continue;
}
/* Check if enclosed by an aggregate. That means the current
function must be a member function of that aggregate. */
- AggregateDeclaration *ad = dsym->isAggregateDeclaration ();
+ AggregateDeclaration *adp = dsym->isAggregateDeclaration ();
- if (ad == NULL)
- goto Lnoframe;
- if (ad->isClassDeclaration () && fdparent == ad->toParent2 ())
- break;
- if (ad->isStructDeclaration () && fdparent == ad->toParent2 ())
- break;
-
- if (!ad->isNested () || !ad->vthis)
+ if (adp != NULL)
{
- Lnoframe:
- error_at (make_location_t (thisfd->loc),
- "cannot get frame pointer to %qs",
- sym->toPrettyChars ());
- return null_pointer_node;
+ if ((adp->isClassDeclaration () || adp->isStructDeclaration ())
+ && fdparent == parent)
+ break;
}
- dsym = dsym->toParent2 ();
+ /* No frame to outer function found. */
+ if (!adp || !adp->isNested () || !adp->vthis)
+ return error_no_frame_access (sym);
+
+ dsym = parent;
}
}
@@ -2724,8 +2731,10 @@ get_framedecl (FuncDeclaration *inner, FuncDeclaration *outer)
break;
}
+ if (fd != outer)
+ return error_no_frame_access (outer);
+
/* Go get our frame record. */
- gcc_assert (fd == outer);
tree frame_type = FRAMEINFO_TYPE (get_frameinfo (outer));
if (frame_type != NULL_TREE)
diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h
index df317d557eb..2be80dd1867 100644
--- a/gcc/d/d-tree.h
+++ b/gcc/d/d-tree.h
@@ -575,6 +575,7 @@ extern tree d_build_call (TypeFunction *, tree, tree, Expressions *);
extern tree d_assert_call (const Loc &, libcall_fn, tree = NULL_TREE);
extern tree build_float_modulus (tree, tree, tree);
extern tree build_vthis_function (tree, tree);
+extern tree error_no_frame_access (Dsymbol *);
extern tree get_frame_for_symbol (Dsymbol *);
extern tree build_vthis (AggregateDeclaration *);
extern void build_closure (FuncDeclaration *);
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index 15eb9a43399..72c8a8cff06 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -1480,6 +1480,11 @@ get_decl_tree (Declaration *decl)
AggregateDeclaration *ad = fd->isThis ();
gcc_assert (ad != NULL);
+ /* The parent function is for the same `this' declaration we are
+ building a chain to. Non-local declaration is inaccessible. */
+ if (fd->vthis == vd)
+ return error_no_frame_access (fd);
+
t = get_decl_tree (fd->vthis);
Dsymbol *outer = fd;
diff --git a/gcc/testsuite/gdc.dg/pr96254a.d b/gcc/testsuite/gdc.dg/pr96254a.d
new file mode 100644
index 00000000000..e5dd1244b94
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr96254a.d
@@ -0,0 +1,28 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96254
+// { dg-do compile }
+struct map(alias fun)
+{
+ @property run()
+ {
+ }
+}
+
+struct Task(Args)
+{
+ Args _args;
+}
+
+template reduce(functions...)
+{
+ auto reduce(Args)(Args args)
+ {
+ alias RTask = Task!(typeof(args));
+ auto task = RTask();
+ }
+}
+
+void main() // { dg-error "'D main' is a nested function and cannot be accessed" }
+{
+ immutable delta = 1;
+ reduce!"a + b"(map!({ immutable x = delta; })());
+}
diff --git a/gcc/testsuite/gdc.dg/pr96254b.d b/gcc/testsuite/gdc.dg/pr96254b.d
new file mode 100644
index 00000000000..02e3c484d26
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr96254b.d
@@ -0,0 +1,24 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96254
+// { dg-do compile }
+mixin template test()
+{
+ int next;
+}
+
+void foo(alias l)()
+{
+ l.next = 0; // { dg-error "cannot get frame pointer to 'D main'" }
+}
+
+void bar(alias l, alias t)()
+{
+ l.next = 0; // { dg-error "cannot get frame pointer to 'D main'" }
+}
+
+void main()
+{
+ mixin test l1;
+ mixin test l2;
+ foo!(l1);
+ bar!(l1,l2);
+}
--
2.25.1
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-08-03 10:00 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-03 10:00 [committed] d: Fix ICE using non-local variable: internal compiler error: Segmentation fault Iain Buclaw
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).