[clang] Properly cache member pointer LLVM types

When not going through the main Clang->LLVM type cache, we'd
accidentally create multiple different opaque types for a member pointer
type.

This allows us to remove the -verify-type-cache flag now that
check-clang passes with it on. We can do the verification in expensive
builds. Previously microsoft-abi-member-pointers.cpp was failing with
-verify-type-cache.

I suspect that there may be more issues when we have multiple member
pointer types and we clear the cache, but we can leave that for later.

Followup to D118744.

Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D119215
This commit is contained in:
Arthur Eubanks 2022-02-07 21:56:28 -08:00
parent c9e6678b56
commit f05a63f9a0
5 changed files with 15 additions and 29 deletions

View file

@ -29,16 +29,6 @@
using namespace clang;
using namespace CodeGen;
#ifndef NDEBUG
#include "llvm/Support/CommandLine.h"
// TODO: turn on by default when defined(EXPENSIVE_CHECKS) once check-clang is
// -verify-type-cache clean.
static llvm::cl::opt<bool> VerifyTypeCache(
"verify-type-cache",
llvm::cl::desc("Verify that the type cache matches the computed type"),
llvm::cl::init(false), llvm::cl::Hidden);
#endif
CodeGenTypes::CodeGenTypes(CodeGenModule &cgm)
: CGM(cgm), Context(cgm.getContext()), TheModule(cgm.getModule()),
Target(cgm.getTarget()), TheCXXABI(cgm.getCXXABI()),
@ -437,14 +427,12 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
TypeCache.find(Ty);
if (TCI != TypeCache.end())
CachedType = TCI->second;
if (CachedType) {
#ifndef NDEBUG
if (!VerifyTypeCache)
return CachedType;
#else
// With expensive checks, check that the type we compute matches the
// cached type.
#ifndef EXPENSIVE_CHECKS
if (CachedType)
return CachedType;
#endif
}
}
// If we don't have it in the cache, convert it now.
@ -784,8 +772,11 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
case Type::MemberPointer: {
auto *MPTy = cast<MemberPointerType>(Ty);
if (!getCXXABI().isMemberPointerConvertible(MPTy)) {
RecordsWithOpaqueMemberPointers.insert(MPTy->getClass());
ResultType = llvm::StructType::create(getLLVMContext());
auto *C = MPTy->getClass();
auto Insertion = RecordsWithOpaqueMemberPointers.insert({C, nullptr});
if (Insertion.second)
Insertion.first->second = llvm::StructType::create(getLLVMContext());
ResultType = Insertion.first->second;
} else {
ResultType = getCXXABI().ConvertMemberPointerType(MPTy);
}
@ -822,13 +813,8 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
}
assert(ResultType && "Didn't convert a type?");
#ifndef NDEBUG
if (CachedType) {
assert(CachedType == ResultType &&
"Cached type doesn't match computed type");
}
#endif
assert((!CachedType || CachedType == ResultType) &&
"Cached type doesn't match computed type");
if (ShouldUseCache)
TypeCache[Ty] = ResultType;

View file

@ -96,7 +96,7 @@ class CodeGenTypes {
/// corresponding llvm::Type.
llvm::DenseMap<const Type *, llvm::Type *> TypeCache;
llvm::SmallSet<const Type *, 8> RecordsWithOpaqueMemberPointers;
llvm::DenseMap<const Type *, llvm::Type *> RecordsWithOpaqueMemberPointers;
static constexpr unsigned FunctionInfosLog2InitSize = 9;
/// Helper for ConvertType.

View file

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -mllvm -verify-type-cache -emit-llvm %s -o - -triple i386-pc-windows-msvc19.16.0 | FileCheck %s
// RUN: %clang_cc1 -emit-llvm %s -o - -triple i386-pc-windows-msvc19.16.0 | FileCheck %s
// REQUIRES: asserts, x86-registered-target
// CHECK: call void @"?dc@z@@SAXU1@@Z"

View file

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -mllvm -verify-type-cache -emit-llvm %s -o - -triple i386-pc-windows-msvc19.16.0 | FileCheck %s
// RUN: %clang_cc1 -emit-llvm %s -o - -triple i386-pc-windows-msvc19.16.0 | FileCheck %s
// REQUIRES: asserts, x86-registered-target
// CHECK-LABEL: define {{.*}}@"?f@@YAXXZ"(

View file

@ -1,4 +1,4 @@
// RUN: %clang_cc1 -mllvm -verify-type-cache -emit-llvm %s -o - -triple i386-pc-windows-msvc19.16.0 | FileCheck %s
// RUN: %clang_cc1 -emit-llvm %s -o - -triple i386-pc-windows-msvc19.16.0 | FileCheck %s
// REQUIRES: asserts, x86-registered-target
// CHECK: call {}* @"?f@@YA?AUz@@XZ"()