Skip to content

Commit 256a0b2

Browse files
committed
[clang] Correct source locations for instantiations of function templates.
This change corrects some cases where the source location for an instantiated specialization of a function template or a member function of a class template was assigned the location of a non-defining declaration rather than the location of the definition the specialization was instantiated from. Fixes llvm#26057 Reviewed By: cor3ntin Differential Revision: https://reviews.llvm.org/D64087
1 parent f89d2be commit 256a0b2

File tree

6 files changed

+31
-11
lines changed

6 files changed

+31
-11
lines changed

clang/docs/ReleaseNotes.rst

+6
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,12 @@ Bug Fixes to C++ Support
291291
pointers on win32.
292292
(`#62594 <https://github.com/llvm/llvm-project/issues/62594>`_)
293293

294+
- Fixed some cases where the source location for an instantiated specialization
295+
of a function template or a member function of a class template was assigned
296+
the location of a non-defining declaration rather than the location of the
297+
definition the specialization was instantiated from.
298+
(`#26057 <https://github.com/llvm/llvm-project/issues/26057>`_`)
299+
294300
Bug Fixes to AST Handling
295301
^^^^^^^^^^^^^^^^^^^^^^^^^
296302
- Fixed an import failure of recursive friend class template.

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -4990,8 +4990,10 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
49904990
// unimported module.
49914991
Function->setVisibleDespiteOwningModule();
49924992

4993-
// Copy the inner loc start from the pattern.
4993+
// Copy the source locations from the pattern.
4994+
Function->setLocation(PatternDecl->getLocation());
49944995
Function->setInnerLocStart(PatternDecl->getInnerLocStart());
4996+
Function->setRangeEnd(PatternDecl->getEndLoc());
49954997

49964998
EnterExpressionEvaluationContext EvalContext(
49974999
*this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);

clang/test/CXX/class/class.compare/class.compare.default/p1.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -209,10 +209,10 @@ bool operator==(e *, int *) = default; // expected-error{{must have at least one
209209

210210
namespace p2085_2 {
211211
template <class T> struct S6 {
212-
// expected-error@+2{{found 'const int &'}}
213-
// expected-error@+1{{found 'const float &'}}
214212
bool operator==(T const &) const;
215213
};
214+
// expected-error@+2{{found 'const int &'}}
215+
// expected-error@+1{{found 'const float &'}}
216216
template <class T> bool S6<T>::operator==(T const &) const = default;
217217

218218
template struct S6<int>; // expected-note{{S6<int>::operator==' requested}}

clang/test/SemaCXX/cxx2b-consteval-propagate.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,14 @@ constexpr int f(T t) {
102102

103103
namespace forward_declare_consteval{
104104
template <typename T>
105-
constexpr int f(T t); // expected-note {{'f<int>' defined here}}
105+
constexpr int f(T t);
106106

107107
auto a = &f<char>;
108108
auto b = &f<int>; // expected-error {{immediate function 'f<int>' used before it is defined}} \
109109
// expected-note {{in instantiation of function template specialization}}
110110

111111
template <typename T>
112-
constexpr int f(T t) {
112+
constexpr int f(T t) { // expected-note {{'f<int>' defined here}}
113113
return id(t); // expected-note {{'f<int>' is an immediate function because its body contains a call to a consteval function 'id' and that call is not a constant expression}}
114114
}
115115
}

clang/test/SemaCXX/member-init.cpp

+14-2
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,11 @@ struct A {
164164

165165
namespace explicit_instantiation {
166166
template<typename T> struct X {
167-
X(); // expected-note {{in instantiation of default member initializer 'explicit_instantiation::X<float>::n' requested here}}
167+
X();
168168
int n = T::error; // expected-error {{type 'float' cannot be used prior to '::' because it has no members}}
169169
};
170170
template struct X<int>; // ok
171-
template<typename T> X<T>::X() {}
171+
template<typename T> X<T>::X() {} // expected-note {{in instantiation of default member initializer 'explicit_instantiation::X<float>::n' requested here}}
172172
template struct X<float>; // expected-note {{in instantiation of member function 'explicit_instantiation::X<float>::X' requested here}}
173173
}
174174

@@ -197,3 +197,15 @@ void foo(T v) {
197197
}
198198
template void foo(int);
199199
}
200+
201+
namespace GH26057 {
202+
template<typename T>
203+
struct S {
204+
S();
205+
int dm = T::error; // expected-error {{type 'int' cannot be used prior to '::' because it has no members}}
206+
};
207+
template<typename T>
208+
S<T>::S() = default; // expected-note {{in instantiation of default member initializer 'GH26057::S<int>::dm' requested here}} \
209+
// expected-note {{in evaluation of exception specification for 'GH26057::S<int>::S' needed here}}
210+
template struct S<int>; // expected-note {{in instantiation of member function 'GH26057::S<int>::S' requested here}}
211+
}

clang/test/SemaTemplate/virtual-member-functions.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77

88
namespace PR5557 {
99
template <class T> struct A {
10-
A(); // expected-note{{instantiation}}
10+
A();
1111
virtual int a(T x);
1212
};
13-
template<class T> A<T>::A() {}
13+
template<class T> A<T>::A() {} // expected-note{{instantiation}}
1414

1515
template<class T> int A<T>::a(T x) {
1616
return *x; // expected-error{{requires pointer operand}}
@@ -33,10 +33,10 @@ void X<int>::f() { }
3333
namespace PR5557_dtor {
3434
template <class T> struct A {
3535
A(); // Don't have an implicit constructor.
36-
~A(); // expected-note{{instantiation}}
36+
~A();
3737
virtual int a(T x);
3838
};
39-
template<class T> A<T>::~A() {}
39+
template<class T> A<T>::~A() {} // expected-note{{instantiation}}
4040

4141
template<class T> int A<T>::a(T x) {
4242
return *x; // expected-error{{requires pointer operand}}

0 commit comments

Comments
 (0)