A constructor defaulted outside the class body is considered user-provided, so we need to handle instantiating it. But functions defaulted inside the class body we still want to treat the same as implicitly declared functions, so the test checks for that as well.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit d91884e4617b54b611b239f619539e0921f2bf9d
Author: Jason Merrill <ja...@redhat.com>
Date:   Sun May 22 15:40:10 2011 -0400

    	PR c++/47544
    	* pt.c (instantiate_decl): Handle =default.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 380b21e..4299733 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -17432,7 +17432,8 @@ instantiate_decl (tree d, int defer_ok,
     args = gen_args;
 
   if (TREE_CODE (d) == FUNCTION_DECL)
-    pattern_defined = (DECL_SAVED_TREE (code_pattern) != NULL_TREE);
+    pattern_defined = (DECL_SAVED_TREE (code_pattern) != NULL_TREE
+		       || DECL_DEFAULTED_OUTSIDE_CLASS_P (code_pattern));
   else
     pattern_defined = ! DECL_IN_AGGR_P (code_pattern);
 
@@ -17627,6 +17628,8 @@ instantiate_decl (tree d, int defer_ok,
       cp_finish_decl (d, init, const_init, NULL_TREE, 0);
       pop_nested_class ();
     }
+  else if (TREE_CODE (d) == FUNCTION_DECL && DECL_DEFAULTED_FN (code_pattern))
+    synthesize_method (d);
   else if (TREE_CODE (d) == FUNCTION_DECL)
     {
       htab_t saved_local_specializations;
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted27.C b/gcc/testsuite/g++.dg/cpp0x/defaulted27.C
new file mode 100644
index 0000000..7d9139d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/defaulted27.C
@@ -0,0 +1,19 @@
+// PR c++/47544
+// { dg-options -std=c++0x }
+// { dg-final { scan-assembler "_ZN1sIiEC2Ev" } }
+// { dg-final { scan-assembler-not "_ZN1sIiED2Ev" } }
+
+template <typename T>
+struct s {
+  s();
+  ~s() = default;
+};
+
+extern template struct s<int>;
+
+template <typename T>
+s<T>::s() = default;
+
+template struct s<int>;
+
+s<int> a;

Reply via email to