[PR,c++/84973] don't defer output of uninstantiated templates

Message ID orzi2yvmk2.fsf@lxoliva.fsfla.org
State New
Headers show
Series
  • [PR,c++/84973] don't defer output of uninstantiated templates
Related show

Commit Message

Alexandre Oliva March 23, 2018, 3:28 p.m.
When an anon struct gets a name through a typedef, we reset its
linkage and that of its members.  Member functions may get vague
linkage, which schedules them for deferred output, but we don't want
to add them to the queue if they're uninstantiated templates,
e.g. because the enclosing function is a template.  They will be added
as needed when the enclosing template is instantiated.

Regstrapped on i686- and x86_64-linux-gnu.  Ok to install?

for  gcc/cp/ChangeLog

	PR c++/84973
	* decl2.c (note_vague_linkage_fn): Don't defer uninstantiated
	templates.

for  gcc/testsuite/ChangeLog

	PR c++/84973
	* g++.dg/template/pr84973.C: New.
	* g++.dg/template/pr84973-2.C: New.
	* g++.dg/template/pr84973-3.C: New.
---
 gcc/cp/decl2.c                            |    3 +++
 gcc/testsuite/g++.dg/template/pr84973-2.C |   13 +++++++++++++
 gcc/testsuite/g++.dg/template/pr84973-3.C |   13 +++++++++++++
 gcc/testsuite/g++.dg/template/pr84973.C   |    8 ++++++++
 4 files changed, 37 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/template/pr84973-2.C
 create mode 100644 gcc/testsuite/g++.dg/template/pr84973-3.C
 create mode 100644 gcc/testsuite/g++.dg/template/pr84973.C


-- 
Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/
You must be the change you wish to see in the world. -- Gandhi
Be Free! -- http://FSFLA.org/   FSF Latin America board member
Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer

Comments

Jason Merrill March 23, 2018, 4:30 p.m. | #1
OK.

On Fri, Mar 23, 2018 at 11:28 AM, Alexandre Oliva <aoliva@redhat.com> wrote:
> When an anon struct gets a name through a typedef, we reset its

> linkage and that of its members.  Member functions may get vague

> linkage, which schedules them for deferred output, but we don't want

> to add them to the queue if they're uninstantiated templates,

> e.g. because the enclosing function is a template.  They will be added

> as needed when the enclosing template is instantiated.

>

> Regstrapped on i686- and x86_64-linux-gnu.  Ok to install?

>

> for  gcc/cp/ChangeLog

>

>         PR c++/84973

>         * decl2.c (note_vague_linkage_fn): Don't defer uninstantiated

>         templates.

>

> for  gcc/testsuite/ChangeLog

>

>         PR c++/84973

>         * g++.dg/template/pr84973.C: New.

>         * g++.dg/template/pr84973-2.C: New.

>         * g++.dg/template/pr84973-3.C: New.

> ---

>  gcc/cp/decl2.c                            |    3 +++

>  gcc/testsuite/g++.dg/template/pr84973-2.C |   13 +++++++++++++

>  gcc/testsuite/g++.dg/template/pr84973-3.C |   13 +++++++++++++

>  gcc/testsuite/g++.dg/template/pr84973.C   |    8 ++++++++

>  4 files changed, 37 insertions(+)

>  create mode 100644 gcc/testsuite/g++.dg/template/pr84973-2.C

>  create mode 100644 gcc/testsuite/g++.dg/template/pr84973-3.C

>  create mode 100644 gcc/testsuite/g++.dg/template/pr84973.C

>

> diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c

> index e522b9ebe55a..fa753749e1a6 100644

> --- a/gcc/cp/decl2.c

> +++ b/gcc/cp/decl2.c

> @@ -739,6 +739,9 @@ check_classfn (tree ctype, tree function, tree template_parms)

>  void

>  note_vague_linkage_fn (tree decl)

>  {

> +  if (processing_template_decl)

> +    return;

> +

>    DECL_DEFER_OUTPUT (decl) = 1;

>    vec_safe_push (deferred_fns, decl);

>  }

> diff --git a/gcc/testsuite/g++.dg/template/pr84973-2.C b/gcc/testsuite/g++.dg/template/pr84973-2.C

> new file mode 100644

> index 000000000000..41c205ad5243

> --- /dev/null

> +++ b/gcc/testsuite/g++.dg/template/pr84973-2.C

> @@ -0,0 +1,13 @@

> +// { dg-do compile }

> +

> +template <int> void a() {

> +  typedef struct {

> +    void b() try { b; } catch (short) { // { dg-error "invalid use" }

> +    }

> +  } c;

> +}

> +

> +int

> +main() {

> +  a<0>();

> +}

> diff --git a/gcc/testsuite/g++.dg/template/pr84973-3.C b/gcc/testsuite/g++.dg/template/pr84973-3.C

> new file mode 100644

> index 000000000000..eeac214f2e1b

> --- /dev/null

> +++ b/gcc/testsuite/g++.dg/template/pr84973-3.C

> @@ -0,0 +1,13 @@

> +// { dg-do link }

> +

> +template <int> void a() {

> +  typedef struct {

> +    void b() try { b(); } catch (short) {

> +    }

> +  } c;

> +}

> +

> +int

> +main() {

> +  a<0>();

> +}

> diff --git a/gcc/testsuite/g++.dg/template/pr84973.C b/gcc/testsuite/g++.dg/template/pr84973.C

> new file mode 100644

> index 000000000000..b3f7170bc0dc

> --- /dev/null

> +++ b/gcc/testsuite/g++.dg/template/pr84973.C

> @@ -0,0 +1,8 @@

> +// { dg-do compile }

> +

> +template <int> void a() {

> +  typedef struct {

> +    void b() try { b; } catch (short) {

> +    }

> +  } c;

> +}

>

> --

> Alexandre Oliva, freedom fighter    http://FSFLA.org/~lxoliva/

> You must be the change you wish to see in the world. -- Gandhi

> Be Free! -- http://FSFLA.org/   FSF Latin America board member

> Free Software Evangelist|Red Hat Brasil GNU Toolchain Engineer

Patch

diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index e522b9ebe55a..fa753749e1a6 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -739,6 +739,9 @@  check_classfn (tree ctype, tree function, tree template_parms)
 void
 note_vague_linkage_fn (tree decl)
 {
+  if (processing_template_decl)
+    return;
+
   DECL_DEFER_OUTPUT (decl) = 1;
   vec_safe_push (deferred_fns, decl);
 }
diff --git a/gcc/testsuite/g++.dg/template/pr84973-2.C b/gcc/testsuite/g++.dg/template/pr84973-2.C
new file mode 100644
index 000000000000..41c205ad5243
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/pr84973-2.C
@@ -0,0 +1,13 @@ 
+// { dg-do compile }
+
+template <int> void a() {
+  typedef struct {
+    void b() try { b; } catch (short) { // { dg-error "invalid use" }
+    }
+  } c;
+}
+
+int
+main() {
+  a<0>();
+}
diff --git a/gcc/testsuite/g++.dg/template/pr84973-3.C b/gcc/testsuite/g++.dg/template/pr84973-3.C
new file mode 100644
index 000000000000..eeac214f2e1b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/pr84973-3.C
@@ -0,0 +1,13 @@ 
+// { dg-do link }
+
+template <int> void a() {
+  typedef struct {
+    void b() try { b(); } catch (short) {
+    }
+  } c;
+}
+
+int
+main() {
+  a<0>();
+}
diff --git a/gcc/testsuite/g++.dg/template/pr84973.C b/gcc/testsuite/g++.dg/template/pr84973.C
new file mode 100644
index 000000000000..b3f7170bc0dc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/pr84973.C
@@ -0,0 +1,8 @@ 
+// { dg-do compile }
+
+template <int> void a() {
+  typedef struct {
+    void b() try { b; } catch (short) {
+    }
+  } c;
+}