mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-15 16:06:06 +00:00

When parsing C++ type construction expressions with list initialization, forward the locations of the braces to Sema. Without these locations, the code coverage pass crashes on the given test case, because the pass relies on getLocEnd() returning a valid location. Here is what this patch does in more detail: - Forwards init-list brace locations to Sema (ParseExprCXX), - Builds an InitializationKind with these locations (SemaExprCXX), and - Uses these locations for constructor initialization (SemaInit). The remaining changes fall out of introducing a new overload for creating direct-list InitializationKinds. Testing: check-clang, and a stage2 coverage-enabled build of clang with asserts enabled. Differential Revision: https://reviews.llvm.org/D41921 llvm-svn: 322729
96 lines
3.1 KiB
C++
96 lines
3.1 KiB
C++
// RUN: %clang_cc1 -triple %itanium_abi_triple -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name classtemplate.cpp %s > %tmapping
|
|
// RUN: FileCheck -input-file %tmapping %s --check-prefix=CHECK-CONSTRUCTOR
|
|
// RUN: FileCheck -input-file %tmapping %s --check-prefix=CHECK-GETTER
|
|
// RUN: FileCheck -input-file %tmapping %s --check-prefix=CHECK-SETTER
|
|
// RUN: FileCheck -input-file %tmapping %s --check-prefix=CHECK-INIT-LIST
|
|
|
|
template<class TT>
|
|
class Test {
|
|
public:
|
|
enum BaseType {
|
|
A, C, G, T, Invalid
|
|
};
|
|
const static int BaseCount = 4;
|
|
double bases[BaseCount];
|
|
|
|
// CHECK-CONSTRUCTOR: _ZN4TestIjEC
|
|
Test() { } // CHECK-CONSTRUCTOR: File 0, [[@LINE]]:10 -> [[@LINE]]:13 = #0
|
|
|
|
// FIXME: It would be nice to emit no-coverage for get, but trying to do this
|
|
// runs afoul of cases like Test3::unmangleable below.
|
|
// FIXME-GETTER: _ZNK4TestIjE3get
|
|
double get(TT position) const { // FIXME-GETTER: File 0, [[@LINE]]:33 -> [[@LINE+2]]:4 = 0
|
|
return bases[position];
|
|
}
|
|
// CHECK-SETTER: _ZN4TestIjE3set
|
|
void set(TT position, double value) { // CHECK-SETTER: File 0, [[@LINE]]:39 -> [[@LINE+2]]:4 = #0
|
|
bases[position] = value;
|
|
}
|
|
};
|
|
|
|
class Test2 {
|
|
// CHECK-CONSTRUCTOR: _ZN5Test2C
|
|
Test2() { } // CHECK-CONSTRUCTOR: File 0, [[@LINE]]:11 -> [[@LINE]]:14 = 0
|
|
// CHECK-GETTER: _ZNK5Test23get
|
|
double get(unsigned position) const { // CHECK-GETTER: File 0, [[@LINE]]:39 -> [[@LINE+2]]:4 = 0
|
|
return 0.0;
|
|
}
|
|
};
|
|
|
|
// Test3::unmangleable can't be mangled, since there isn't a complete type for
|
|
// the __is_final type trait expression. This would cause errors if we try to
|
|
// emit a no-coverage mapping for the method.
|
|
template <class T, bool = __is_final(T)> class UninstantiatedClassWithTraits {};
|
|
template <class T> class Test3 {
|
|
void unmangleable(UninstantiatedClassWithTraits<T> x) {}
|
|
};
|
|
|
|
void abort() __attribute__((noreturn));
|
|
|
|
namespace std {
|
|
typedef decltype(sizeof(int)) size_t;
|
|
|
|
template <typename E> struct initializer_list {
|
|
const E *p;
|
|
size_t n;
|
|
initializer_list(const E *p, size_t n) : p(p), n(n) {}
|
|
};
|
|
|
|
template <typename F, typename S> struct pair {
|
|
F f;
|
|
S s;
|
|
pair(const F &f, const S &s) : f(f), s(s) {}
|
|
};
|
|
|
|
struct string {
|
|
const char *str;
|
|
string() { abort(); }
|
|
string(const char *S) : str(S) {}
|
|
~string() { abort(); }
|
|
};
|
|
|
|
template<typename K, typename V>
|
|
struct map {
|
|
using T = pair<K, V>;
|
|
map(initializer_list<T> i, const string &s = string()) {}
|
|
~map() { abort(); }
|
|
};
|
|
|
|
}; // namespace std
|
|
|
|
// CHECK-INIT-LIST-LABEL: _Z5Test4v:
|
|
std::map<int, int> Test4() { // CHECK-INIT-LIST: File 0, [[@LINE]]:28 -> [[@LINE+3]]:2 = #0
|
|
abort();
|
|
return std::map<int, int>{{0, 0}}; // CHECK-INIT-LIST-NEXT: [[@LINE]]:3 -> [[@LINE]]:36 = 0
|
|
}
|
|
|
|
int main() {
|
|
Test<unsigned> t;
|
|
t.set(Test<unsigned>::A, 5.5);
|
|
t.set(Test<unsigned>::T, 5.6);
|
|
t.set(Test<unsigned>::G, 5.7);
|
|
t.set(Test<unsigned>::C, 5.8);
|
|
Test4();
|
|
return 0;
|
|
}
|