diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 748f37df333eddba7e5660b3d1246a7ed32f059c..04f9af72d8f274355aaa505d793a05dabfb55282 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2010-07-20  Jeffrey Yasskin  <jyasskin@google.com>
+
+	PR c++/44641
+	* pt.c (instantiate_class_template): Propagate the template's
+	location to its instance.
+
 2010-07-20  Jason Merrill  <jason@redhat.com>
 
 	PR c++/44967
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index b61890737dfb94a9efe08e60862d47a04fb77e0b..7a331479d8b515bbe7e2aaf474c27a55a12d0554 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -7832,7 +7832,8 @@ instantiate_class_template (tree type)
   /* Set the input location to the most specialized template definition.
      This is needed if tsubsting causes an error.  */
   typedecl = TYPE_MAIN_DECL (pattern);
-  input_location = DECL_SOURCE_LOCATION (typedecl);
+  input_location = DECL_SOURCE_LOCATION (TYPE_NAME (type)) =
+    DECL_SOURCE_LOCATION (typedecl);
 
   TYPE_HAS_USER_CONSTRUCTOR (type) = TYPE_HAS_USER_CONSTRUCTOR (pattern);
   TYPE_HAS_NEW_OPERATOR (type) = TYPE_HAS_NEW_OPERATOR (pattern);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9772252bc76f722ff8a2668b759c469430eb373f..d5e18023f437a32ad0cfdc41880204ce80250125 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2010-07-20  Jeffrey Yasskin  <jyasskin@google.com>
+
+	* lib/scanasm.exp (dg-function-on-line): Test that a function is
+	defined on the current line.
+	* g++.dg/debug/dwarf2/lineno-simple1.C: New. Line number sanity test.
+	* g++.dg/debug/dwarf2/pr44641.C: New.
+
 2010-07-20  Nathan Froyd  <froydnj@codesourcery.com>
 
 	* gcc.target/powerpc/block-move-1.c: New test.
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/lineno-simple1.C b/gcc/testsuite/g++.dg/debug/dwarf2/lineno-simple1.C
new file mode 100644
index 0000000000000000000000000000000000000000..e0ef7f71ca34188eea6271a2e2e669f4bd990a1c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/lineno-simple1.C
@@ -0,0 +1,13 @@
+// { dg-do compile }
+// { dg-options "-g -O0 -dA" }
+
+struct C {  // { dg-function-on-line {_ZN1CC[12]Ev} }
+  virtual void
+  foo() {}  // { dg-function-on-line _ZN1C3fooEv }
+};
+static C dummy;
+
+int
+main (void)
+{  // { dg-function-on-line main }
+}
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/pr44641.C b/gcc/testsuite/g++.dg/debug/dwarf2/pr44641.C
new file mode 100644
index 0000000000000000000000000000000000000000..2df002f6b007c05ee88952dfd8cd09ce5087549f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/pr44641.C
@@ -0,0 +1,41 @@
+// Origin: PR 44641
+// { dg-do compile }
+// { dg-options "-g -O0 -dA" }
+
+template <class A> struct MisplacedDbg;
+template<class T> struct MisplacedDbg<T*>;
+struct Full;
+template<> struct MisplacedDbg<Full>;
+
+struct Arg;
+typedef MisplacedDbg<Arg> Typedef1;
+typedef MisplacedDbg<Arg*> Typedef2;
+typedef MisplacedDbg<Full> Typedef3;
+
+template<typename T> struct Base  {
+  virtual ~Base() {
+  }
+};
+
+template <>
+struct MisplacedDbg<Full>  // { dg-function-on-line {_ZN12MisplacedDbgI4FullEC[12]Ev} }
+                           // { dg-function-on-line {_ZN12MisplacedDbgI4FullED0Ev} { target *-*-* } 21 }
+
+    : public Base<int> {
+};
+
+template <class T>
+struct MisplacedDbg<T*>  // { dg-function-on-line {_ZN12MisplacedDbgIP3ArgEC[12]Ev} }
+                         // { dg-function-on-line {_ZN12MisplacedDbgIP3ArgED0Ev} { target *-*-* } 28 }
+    : public Base<int> {
+};
+
+template <class A>
+struct MisplacedDbg  // { dg-function-on-line {_ZN12MisplacedDbgI3ArgEC[12]Ev} }
+                     // { dg-function-on-line {_ZN12MisplacedDbgI3ArgED0Ev} { target *-*-* } 34 }
+    : public Base<int> {
+};
+
+static MisplacedDbg<Arg> static_var1;
+static MisplacedDbg<Arg*> static_var2;
+static MisplacedDbg<Full> static_var3;
diff --git a/gcc/testsuite/lib/scanasm.exp b/gcc/testsuite/lib/scanasm.exp
index abc01b7cc55a9809e1b4d199f711faf4f46f884b..aa8383d43a99bed456a6cdd1c45459fae90a35db 100644
--- a/gcc/testsuite/lib/scanasm.exp
+++ b/gcc/testsuite/lib/scanasm.exp
@@ -291,3 +291,40 @@ proc scan-assembler-dem-not { args } {
 	fail "$testcase scan-assembler-dem-not $pp_pattern"
     }
 }
+
+# Utility for testing that a function is defined on the current line.
+# Call pass if so, otherwise fail.  Invoked directly; the file must
+# have been compiled with -g -dA.
+#
+# Argument 0 is the current line, passed implicitly by dejagnu
+# Argument 1 is the function to check
+# Argument 2 handles expected failures and the like
+# Argument 3 is "." to match the current line, or an integer to match
+# an explicit line.
+proc dg-function-on-line { args } {
+    # Upvar from dg-final:
+    upvar dg-final-code final-code
+
+    set line [lindex $args 0]
+    set symbol [lindex $args 1]
+    set failures [lindex $args 2]
+
+    if { [llength $args] >= 4 } {
+	switch [lindex $args 3] {
+	    "." { }
+	    "default" { set line [lindex $args 3] }
+	}
+    }
+
+    set pattern [format {%s:[^\t]*(\t.file[^\t]*)?\t# \S*:%d\n} \
+                 $symbol $line]
+
+    # The lack of spaces around $pattern is important, since they'd
+    # become part of the regex scan-assembler tries to match.
+    set cmd "scan-assembler {$pattern}"
+    if { [llength $args] >= 3 } {
+        set cmd "$cmd {$failures}"
+    }
+
+    append final-code "$cmd\n"
+}