This patch replaces member accesses to declaration references during template instantiation if the context is the unevaluated context and the class does not contain the declaration. The replacement fixes the issue #58674. Unlike previous fixes such as D143840, it checks the membership during instantiation rather than right after parsing, so the check is more accurate and efficient. This patch also includes cases that previous fixes had once failed on. Differential Revision: https://reviews.llvm.org/D145491
61 lines
1.3 KiB
C++
61 lines
1.3 KiB
C++
// RUN: %clang_cc1 -triple=x86_64-unknown-linux -emit-llvm %s -o - | FileCheck \
|
|
// RUN: -check-prefix=CHECK-1 %s
|
|
// RUN: %clang_cc1 -triple=x86_64-unknown-linux -emit-llvm %s -o - | FileCheck \
|
|
// RUN: -check-prefix=CHECK-2 %s
|
|
// RUN: %clang_cc1 -triple=x86_64-unknown-linux -emit-llvm %s -o - | FileCheck \
|
|
// RUN: -check-prefix=CHECK-3 %s
|
|
|
|
// CHECK-1: [[FOO:%.+]] = type { float }
|
|
struct foo {
|
|
float val;
|
|
};
|
|
|
|
template <typename T> struct bar : T {
|
|
};
|
|
|
|
struct baz : bar<foo> {
|
|
// CHECK-1: define{{.*}} float @_ZN3baz3getEv
|
|
// CHECK-1: {{%.+}} = getelementptr inbounds [[FOO]], ptr {{%.+}}, i32 0, i32 0
|
|
float get() {
|
|
return val;
|
|
}
|
|
};
|
|
|
|
int qux() {
|
|
auto f = baz{};
|
|
return f.get();
|
|
}
|
|
|
|
// CHECK-2: [[F:%.+]] = type { ptr }
|
|
struct f {
|
|
void *g;
|
|
};
|
|
|
|
template <typename j> struct k : j {
|
|
// CHECK-2: define{{.*}} void @_ZN1kI1fE1lEv
|
|
// CHECK-2: {{%.+}} = getelementptr inbounds [[F]], ptr {{%.+}}, i32 0, i32 0
|
|
virtual void l(){ (void)f::g; }
|
|
};
|
|
|
|
k<f> q;
|
|
|
|
// CHECK-3: [[BASE:%.+]] = type { i32 }
|
|
class Base {
|
|
protected:
|
|
int member;
|
|
};
|
|
|
|
template <typename Parent>
|
|
struct Subclass : public Parent {
|
|
// CHECK-3: define{{.*}} i32 @_ZN8SubclassI4BaseE4funcEv
|
|
// CHECK-3: {{%.+}} = getelementptr inbounds [[BASE]], ptr {{%.+}}, i32 0, i32 0
|
|
int func() { return Base::member; }
|
|
};
|
|
|
|
using Impl = Subclass<Base>;
|
|
|
|
int use() {
|
|
Impl i;
|
|
return i.func();
|
|
}
|