Skip to content

Commit 17eed25

Browse files
authored
Merge branch 'main' into fix-webkit-treat-asm-trap-as-trivial
2 parents 9d3e26d + 202356d commit 17eed25

File tree

65 files changed

+2891
-1070
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+2891
-1070
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,12 @@ Improvements to Clang's diagnostics
228228
- Fixed false positive in ``-Wmissing-noreturn`` diagnostic when it was requiring the usage of
229229
``[[noreturn]]`` on lambdas before C++23 (#GH154493).
230230

231+
- Clang now diagnoses the use of ``#`` and ``##`` preprocessor tokens in
232+
attribute argument lists in C++ when ``-pedantic`` is enabled. The operators
233+
can be used in macro replacement lists with the usual preprocessor semantics,
234+
however, non-preprocessor use of tokens now triggers a pedantic warning in C++.
235+
Compilation in C mode is unchanged, and still permits these tokens to be used. (#GH147217)
236+
231237
Improvements to Clang's time-trace
232238
----------------------------------
233239

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,9 @@ def err_ms_property_expected_comma_or_rparen : Error<
830830
"expected ',' or ')' at end of property accessor list">;
831831
def err_ms_property_initializer : Error<
832832
"property declaration cannot have a default member initializer">;
833+
def ext_invalid_attribute_argument
834+
: Extension<"'%0' is not allowed in an attribute argument list">,
835+
InGroup<DiagGroup<"attribute-preprocessor-tokens">>;
833836

834837
def err_assume_attr_expects_cond_expr : Error<
835838
"use of this expression in an %0 attribute requires parentheses">;

clang/include/clang/CIR/MissingFeatures.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,12 +273,12 @@ struct MissingFeatures {
273273
static bool thunks() { return false; }
274274
static bool tryEmitAsConstant() { return false; }
275275
static bool typeChecks() { return false; }
276-
static bool vtableInitializer() { return false; }
277276
static bool weakRefReference() { return false; }
278277
static bool writebacks() { return false; }
279278
static bool appleKext() { return false; }
280279
static bool dtorCleanups() { return false; }
281280
static bool vtableInitialization() { return false; }
281+
static bool vtableEmitMetadata() { return false; }
282282
static bool vtableRelativeLayout() { return false; }
283283
static bool msvcBuiltins() { return false; }
284284
static bool vaArgABILowering() { return false; }

clang/lib/CIR/CodeGen/CIRGenCXXABI.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ class CIRGenCXXABI {
9595
isVirtualOffsetNeededForVTableField(CIRGenFunction &cgf,
9696
CIRGenFunction::VPtr vptr) = 0;
9797

98+
/// Emits the VTable definitions required for the given record type.
99+
virtual void emitVTableDefinitions(CIRGenVTables &cgvt,
100+
const CXXRecordDecl *rd) = 0;
101+
98102
/// Returns true if the given destructor type should be emitted as a linkonce
99103
/// delegating thunk, regardless of whether the dtor is defined in this TU or
100104
/// not.

clang/lib/CIR/CodeGen/CIRGenCall.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ CIRGenFunctionInfo::create(CanQualType resultType,
4242
return fi;
4343
}
4444

45+
cir::FuncType CIRGenTypes::getFunctionType(GlobalDecl gd) {
46+
const CIRGenFunctionInfo &fi = arrangeGlobalDeclaration(gd);
47+
return getFunctionType(fi);
48+
}
49+
4550
cir::FuncType CIRGenTypes::getFunctionType(const CIRGenFunctionInfo &info) {
4651
mlir::Type resultType = convertType(info.getReturnType());
4752
SmallVector<mlir::Type, 8> argTypes;
@@ -55,6 +60,16 @@ cir::FuncType CIRGenTypes::getFunctionType(const CIRGenFunctionInfo &info) {
5560
info.isVariadic());
5661
}
5762

63+
cir::FuncType CIRGenTypes::getFunctionTypeForVTable(GlobalDecl gd) {
64+
const CXXMethodDecl *md = cast<CXXMethodDecl>(gd.getDecl());
65+
const FunctionProtoType *fpt = md->getType()->getAs<FunctionProtoType>();
66+
67+
if (!isFuncTypeConvertible(fpt))
68+
cgm.errorNYI("getFunctionTypeForVTable: non-convertible function type");
69+
70+
return getFunctionType(gd);
71+
}
72+
5873
CIRGenCallee CIRGenCallee::prepareConcreteCallee(CIRGenFunction &cgf) const {
5974
if (isVirtual()) {
6075
const CallExpr *ce = getVirtualCallExpr();

clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ class CIRGenItaniumCXXABI : public CIRGenCXXABI {
8181
CIRGenFunction &cgf, const clang::CXXRecordDecl *vtableClass,
8282
clang::BaseSubobject base,
8383
const clang::CXXRecordDecl *nearestVBase) override;
84+
void emitVTableDefinitions(CIRGenVTables &cgvt,
85+
const CXXRecordDecl *rd) override;
8486

8587
bool doStructorsInitializeVPtrs(const CXXRecordDecl *vtableClass) override {
8688
return true;
@@ -270,6 +272,67 @@ bool CIRGenItaniumCXXABI::needsVTTParameter(GlobalDecl gd) {
270272
return false;
271273
}
272274

275+
void CIRGenItaniumCXXABI::emitVTableDefinitions(CIRGenVTables &cgvt,
276+
const CXXRecordDecl *rd) {
277+
cir::GlobalOp vtable = getAddrOfVTable(rd, CharUnits());
278+
if (vtable.hasInitializer())
279+
return;
280+
281+
ItaniumVTableContext &vtContext = cgm.getItaniumVTableContext();
282+
const VTableLayout &vtLayout = vtContext.getVTableLayout(rd);
283+
cir::GlobalLinkageKind linkage = cgm.getVTableLinkage(rd);
284+
mlir::Attribute rtti =
285+
cgm.getAddrOfRTTIDescriptor(cgm.getLoc(rd->getBeginLoc()),
286+
cgm.getASTContext().getCanonicalTagType(rd));
287+
288+
// Classic codegen uses ConstantInitBuilder here, which is a very general
289+
// and feature-rich class to generate initializers for global values.
290+
// For now, this is using a simpler approach to create the initializer in CIR.
291+
cgvt.createVTableInitializer(vtable, vtLayout, rtti,
292+
cir::isLocalLinkage(linkage));
293+
294+
// Set the correct linkage.
295+
vtable.setLinkage(linkage);
296+
297+
if (cgm.supportsCOMDAT() && cir::isWeakForLinker(linkage))
298+
vtable.setComdat(true);
299+
300+
// Set the right visibility.
301+
cgm.setGVProperties(vtable, rd);
302+
303+
// If this is the magic class __cxxabiv1::__fundamental_type_info,
304+
// we will emit the typeinfo for the fundamental types. This is the
305+
// same behaviour as GCC.
306+
const DeclContext *DC = rd->getDeclContext();
307+
if (rd->getIdentifier() &&
308+
rd->getIdentifier()->isStr("__fundamental_type_info") &&
309+
isa<NamespaceDecl>(DC) && cast<NamespaceDecl>(DC)->getIdentifier() &&
310+
cast<NamespaceDecl>(DC)->getIdentifier()->isStr("__cxxabiv1") &&
311+
DC->getParent()->isTranslationUnit()) {
312+
cgm.errorNYI(rd->getSourceRange(),
313+
"emitVTableDefinitions: __fundamental_type_info");
314+
}
315+
316+
auto vtableAsGlobalValue = dyn_cast<cir::CIRGlobalValueInterface>(*vtable);
317+
assert(vtableAsGlobalValue && "VTable must support CIRGlobalValueInterface");
318+
// Always emit type metadata on non-available_externally definitions, and on
319+
// available_externally definitions if we are performing whole program
320+
// devirtualization. For WPD we need the type metadata on all vtable
321+
// definitions to ensure we associate derived classes with base classes
322+
// defined in headers but with a strong definition only in a shared
323+
// library.
324+
assert(!cir::MissingFeatures::vtableEmitMetadata());
325+
if (cgm.getCodeGenOpts().WholeProgramVTables) {
326+
cgm.errorNYI(rd->getSourceRange(),
327+
"emitVTableDefinitions: WholeProgramVTables");
328+
}
329+
330+
assert(!cir::MissingFeatures::vtableRelativeLayout());
331+
if (vtContext.isRelativeLayout()) {
332+
cgm.errorNYI(rd->getSourceRange(), "vtableRelativeLayout");
333+
}
334+
}
335+
273336
void CIRGenItaniumCXXABI::emitDestructorCall(
274337
CIRGenFunction &cgf, const CXXDestructorDecl *dd, CXXDtorType type,
275338
bool forVirtualBase, bool delegating, Address thisAddr, QualType thisTy) {

clang/lib/CIR/CodeGen/CIRGenModule.cpp

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,11 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
103103
PtrDiffTy =
104104
cir::IntType::get(&getMLIRContext(), sizeTypeSize, /*isSigned=*/true);
105105

106-
theModule->setAttr(
107-
cir::CIRDialect::getSourceLanguageAttrName(),
108-
cir::SourceLanguageAttr::get(&mlirContext, getCIRSourceLanguage()));
106+
std::optional<cir::SourceLanguage> sourceLanguage = getCIRSourceLanguage();
107+
if (sourceLanguage)
108+
theModule->setAttr(
109+
cir::CIRDialect::getSourceLanguageAttrName(),
110+
cir::SourceLanguageAttr::get(&mlirContext, *sourceLanguage));
109111
theModule->setAttr(cir::CIRDialect::getTripleAttrName(),
110112
builder.getStringAttr(getTriple().str()));
111113

@@ -513,7 +515,7 @@ void CIRGenModule::setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op) {
513515
assert(!cir::MissingFeatures::setTargetAttributes());
514516
}
515517

516-
cir::SourceLanguage CIRGenModule::getCIRSourceLanguage() const {
518+
std::optional<cir::SourceLanguage> CIRGenModule::getCIRSourceLanguage() const {
517519
using ClangStd = clang::LangStandard;
518520
using CIRLang = cir::SourceLanguage;
519521
auto opts = getLangOpts();
@@ -528,6 +530,7 @@ cir::SourceLanguage CIRGenModule::getCIRSourceLanguage() const {
528530
// TODO(cir): support remaining source languages.
529531
assert(!cir::MissingFeatures::sourceLanguageCases());
530532
errorNYI("CIR does not yet support the given source language");
533+
return std::nullopt;
531534
}
532535

533536
static void setLinkageForGV(cir::GlobalOp &gv, const NamedDecl *nd) {
@@ -845,7 +848,7 @@ void CIRGenModule::emitGlobalDefinition(clang::GlobalDecl gd,
845848
emitGlobalFunctionDefinition(gd, op);
846849

847850
if (method->isVirtual())
848-
errorNYI(method->getSourceRange(), "virtual member function");
851+
getVTables().emitThunks(gd);
849852

850853
return;
851854
}
@@ -2151,6 +2154,18 @@ bool CIRGenModule::verifyModule() const {
21512154
return mlir::verify(theModule).succeeded();
21522155
}
21532156

2157+
mlir::Attribute CIRGenModule::getAddrOfRTTIDescriptor(mlir::Location loc,
2158+
QualType ty, bool forEh) {
2159+
// Return a bogus pointer if RTTI is disabled, unless it's for EH.
2160+
// FIXME: should we even be calling this method if RTTI is disabled
2161+
// and it's not for EH?
2162+
if (!shouldEmitRTTI(forEh))
2163+
return builder.getConstNullPtrAttr(builder.getUInt8PtrTy());
2164+
2165+
errorNYI(loc, "getAddrOfRTTIDescriptor");
2166+
return mlir::Attribute();
2167+
}
2168+
21542169
// TODO(cir): this can be shared with LLVM codegen.
21552170
CharUnits CIRGenModule::computeNonVirtualBaseClassOffset(
21562171
const CXXRecordDecl *derivedClass,

clang/lib/CIR/CodeGen/CIRGenModule.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,16 @@ class CIRGenModule : public CIRGenTypeCache {
190190
mlir::Location loc, llvm::StringRef name, mlir::Type ty,
191191
cir::GlobalLinkageKind linkage, clang::CharUnits alignment);
192192

193+
void emitVTable(const CXXRecordDecl *rd);
194+
195+
/// Return the appropriate linkage for the vtable, VTT, and type information
196+
/// of the given class.
197+
cir::GlobalLinkageKind getVTableLinkage(const CXXRecordDecl *rd);
198+
199+
/// Get the address of the RTTI descriptor for the given type.
200+
mlir::Attribute getAddrOfRTTIDescriptor(mlir::Location loc, QualType ty,
201+
bool forEH = false);
202+
193203
/// Return a constant array for the given string.
194204
mlir::Attribute getConstantArrayFromStringLiteral(const StringLiteral *e);
195205

@@ -290,6 +300,13 @@ class CIRGenModule : public CIRGenTypeCache {
290300
getAddrOfGlobal(clang::GlobalDecl gd,
291301
ForDefinition_t isForDefinition = NotForDefinition);
292302

303+
// Return whether RTTI information should be emitted for this target.
304+
bool shouldEmitRTTI(bool forEH = false) {
305+
return (forEH || getLangOpts().RTTI) && !getLangOpts().CUDAIsDevice &&
306+
!(getLangOpts().OpenMP && getLangOpts().OpenMPIsTargetDevice &&
307+
getTriple().isNVPTX());
308+
}
309+
293310
/// Emit type info if type of an expression is a variably modified
294311
/// type. Also emit proper debug info for cast types.
295312
void emitExplicitCastExprType(const ExplicitCastExpr *e,
@@ -463,7 +480,7 @@ class CIRGenModule : public CIRGenTypeCache {
463480
void setNonAliasAttributes(GlobalDecl gd, mlir::Operation *op);
464481

465482
/// Map source language used to a CIR attribute.
466-
cir::SourceLanguage getCIRSourceLanguage() const;
483+
std::optional<cir::SourceLanguage> getCIRSourceLanguage() const;
467484
};
468485
} // namespace CIRGen
469486

clang/lib/CIR/CodeGen/CIRGenTypes.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,13 @@ class CIRGenTypes {
130130
/// Get the CIR function type for \arg Info.
131131
cir::FuncType getFunctionType(const CIRGenFunctionInfo &info);
132132

133+
cir::FuncType getFunctionType(clang::GlobalDecl gd);
134+
135+
/// Get the CIR function type for use in a vtable, given a CXXMethodDecl. If
136+
/// the method has an incomplete return type, and/or incomplete argument
137+
/// types, this will return the opaque type.
138+
cir::FuncType getFunctionTypeForVTable(clang::GlobalDecl gd);
139+
133140
// The arrangement methods are split into three families:
134141
// - those meant to drive the signature and prologue/epilogue
135142
// of a function declaration or definition,

0 commit comments

Comments
 (0)