зеркало из https://github.com/github/codeql.git
Merge pull request #40 from nickrolfe/dependent_template_alias
C++: dependent template alias
This commit is contained in:
Коммит
692f416143
|
@ -0,0 +1,37 @@
|
|||
|
||||
template <typename>
|
||||
using Z = int;
|
||||
|
||||
template <typename T, typename U = int>
|
||||
struct Thing {
|
||||
int x;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct Thing<T, Z<typename T::Undefined>> {
|
||||
int y;
|
||||
};
|
||||
|
||||
// Note that float::Undefined is an error, so this should match the primary
|
||||
// template, not the partial specialization.
|
||||
Thing<float> thing_float;
|
||||
|
||||
void f() {
|
||||
// If we incorrectly matched the partial specialization, this write to x would
|
||||
// be an error.
|
||||
thing_float.x = 1;
|
||||
}
|
||||
|
||||
// Now, a type that actually does define Undefined
|
||||
struct S {
|
||||
using Undefined = int;
|
||||
};
|
||||
|
||||
// S::Undefined is okay, so this should match the partial specialization.
|
||||
Thing<S> thing_s;
|
||||
|
||||
void g() {
|
||||
// If we incorrectly matched the primary template, this write to y would be an
|
||||
// error.
|
||||
thing_s.y = 1;
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
| test.cpp:17:14:17:24 | thing_float | test.cpp:6:8:6:12 | Thing<float, int> | test.cpp:7:7:7:7 | x |
|
||||
| test.cpp:31:10:31:16 | thing_s | test.cpp:11:8:11:41 | Thing<S, int> | test.cpp:12:7:12:7 | y |
|
|
@ -0,0 +1,6 @@
|
|||
import cpp
|
||||
|
||||
from Variable v, Class c
|
||||
where c = v.getType()
|
||||
and v.getFile().getBaseName() = "test.cpp"
|
||||
select v, c, c.getAMemberVariable()
|
|
@ -12,10 +12,10 @@ void functions() {
|
|||
b(static_cast<my_int>(0));
|
||||
c<int>(0);
|
||||
d<my_int>(0);
|
||||
|
||||
|
||||
e<int>(0);
|
||||
e<my_int>(0);
|
||||
|
||||
|
||||
f<my_int>(0);
|
||||
f<int>(0);
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ template <typename TD> struct D {};
|
|||
template <typename TE> struct E {};
|
||||
template <typename TF> struct F {};
|
||||
template <typename TG> struct G {};
|
||||
template <typename TH> struct H {};
|
||||
|
||||
struct S { int x; };
|
||||
typedef S S_t;
|
||||
|
@ -34,18 +35,27 @@ typedef S S_t;
|
|||
typedef C<int> C1;
|
||||
typedef D<my_int> D1;
|
||||
|
||||
template <typename TZ>
|
||||
using Z = TZ;
|
||||
|
||||
void types() {
|
||||
A<int>* a;
|
||||
B<my_int>* b;
|
||||
C1 c;
|
||||
D1 d;
|
||||
|
||||
|
||||
E<int> e1;
|
||||
E<my_int> e2;
|
||||
|
||||
E<Z<int>> e3;
|
||||
|
||||
F<my_int> f1;
|
||||
F<int> f2;
|
||||
|
||||
F<Z<int>> f3;
|
||||
|
||||
H<Z<int>> h1;
|
||||
H<my_int> h2;
|
||||
H<int> h3;
|
||||
|
||||
G<my_int*> g1;
|
||||
G<const my_int* const> g2;
|
||||
G<my_int**&> g3;
|
||||
|
|
|
@ -12,12 +12,14 @@
|
|||
| F<int> | int |
|
||||
| G<..(*)(..)> | pointer to {function returning {pointer to {int}} with arguments (int)} |
|
||||
| G<TG> | TG |
|
||||
| G<__attribute((vector_size(32))) int> | {GNU 8 element vector of {int}} |
|
||||
| G<__attribute((vector_size(32))) int> | GNU 8 element vector of {int} |
|
||||
| G<const int *const> | const {pointer to {const {int}}} |
|
||||
| G<int **&> | reference to {pointer to {pointer to {int}}} |
|
||||
| G<int *> | pointer to {int} |
|
||||
| G<int S::*> | pointer to member of S with type {int} |
|
||||
| G<int(&)[3]> | reference to {array of 3 {int}} |
|
||||
| H<TH> | TH |
|
||||
| H<int> | int |
|
||||
| a | Ta |
|
||||
| a | int |
|
||||
| b | Tb |
|
||||
|
|
Загрузка…
Ссылка в новой задаче